/*
 * Copyright 2022 The Kubernetes Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/**
 * This module implements a Webpack loader that inlines markdown
 * snippets at build time.
 *
 */
import Debug from 'debug';
import needle from 'needle';
import { readFile } from 'fs';
import { validate } from 'schema-utils';
import { getOptions } from 'loader-utils';
import inlineSnippets from './snippets';
const debug = Debug('snippets-main');
/** The schema for our Webpack loader */
const schema = {
    additionalProperties: false,
    properties: {
        esModule: {
            type: 'boolean'
        }
    },
    type: 'object'
};
/** Fetch a local file */
function fetchFile(filepath) {
    return __awaiter(this, void 0, void 0, function* () {
        debug('fetching file', filepath);
        return new Promise((resolve, reject) => {
            readFile(filepath, (err, data) => {
                if (err) {
                    debug('error fetching file', err);
                    reject(err);
                }
                else {
                    debug('successfully fetched file', filepath);
                    resolve(data.toString());
                }
            });
        });
    });
}
/** Fetch a remote file */
function fetchUrl(filepath) {
    return __awaiter(this, void 0, void 0, function* () {
        debug('fetching url', filepath);
        const data = yield needle('get', filepath);
        if (data.statusCode !== 200) {
            debug('error fetching url', filepath, data.statusCode);
            const error = new Error(data.body);
            error.code = data.statusCode;
            throw error;
        }
        else {
            debug('successfully fetched url', filepath, data.body);
            return data.body;
        }
    });
}
/**
 * This is the entrypoint for our webpack loader
 * @param   {String}  content   Markdown file content
 */
function loader(data, srcFilePath = this.resourcePath) {
    const callback = this.async();
    const options = getOptions(this);
    validate(schema, options, { name: 'snippet-inliner' });
    const REPL = {
        rexec: (cmdline) => __awaiter(this, void 0, void 0, function* () {
            const filepath = cmdline
                .replace(/^vfs (_fetchfile|fstat)\s+/, '')
                .replace(/--with-data/g, '')
                .trim();
            if (/^vfs _fetchfile/.test(cmdline)) {
                const content = [yield fetchUrl(filepath)];
                return { mode: 'raw', content };
            }
            else if (/^vfs fstat/.test(cmdline)) {
                const content = {
                    data: yield fetchFile(filepath)
                };
                return { mode: 'raw', content };
            }
            else {
                throw new Error(`Unsupported operation ${cmdline}`);
            }
        }),
        pexec: undefined,
        reexec: undefined,
        qexec: undefined,
        click: undefined,
        split: undefined,
        encodeComponent: undefined
    };
    const esModule = typeof options.esModule !== 'undefined' ? options.esModule : true;
    const exportIt = (data) => {
        const json = JSON.stringify(data)
            .replace(/\u2028/g, '\\u2028')
            .replace(/\u2029/g, '\\u2029');
        return (esModule ? 'export default ' : 'module.exports = ') + json;
    };
    inlineSnippets({ REPL })(data, srcFilePath)
        .then(exportIt)
        .then(data => callback(null, data))
        .catch(callback);
}
/** Fake `this` for non-webpack "main" usage */
class Fake {
    async() {
        return (err, data) => {
            if (err) {
                throw err;
            }
            else {
                console.log(data);
            }
        };
    }
}
if (require.main === module) {
    // called directly from the command line
    readFile(process.argv[2], (err, data) => {
        if (err) {
            throw err;
        }
        else {
            loader.bind(new Fake())(data.toString(), process.argv[2]);
        }
    });
}
else {
    // nothing special to do if we are coming from webpack
}
export default loader;
//# sourceMappingURL=snippets-inliner.js.map