'use strict';

var yargs = require('yargs');
var fs = require('fs');
var path = require('path');
var transformAnalyzerResult = require('./chunk-transform-analyzer-result-jzWAvD19.js');
var fastGlob = require('fast-glob');
var tsModule = require('typescript');
require('ts-simple-type');

function _interopNamespaceDefault(e) {
    var n = Object.create(null);
    if (e) {
        Object.keys(e).forEach(function (k) {
            if (k !== 'default') {
                var d = Object.getOwnPropertyDescriptor(e, k);
                Object.defineProperty(n, k, d.get ? d : {
                    enumerable: true,
                    get: function () { return e[k]; }
                });
            }
        });
    }
    n.default = e;
    return Object.freeze(n);
}

var yargs__namespace = /*#__PURE__*/_interopNamespaceDefault(yargs);

/**
 * The most general version of compiler options.
 */
const defaultOptions = {
    noEmitOnError: false,
    allowJs: true,
    maxNodeModuleJsDepth: 3,
    experimentalDecorators: true,
    target: tsModule.ScriptTarget.Latest,
    downlevelIteration: true,
    module: tsModule.ModuleKind.ESNext,
    //module: ModuleKind.CommonJS,
    //lib: ["ESNext", "DOM", "DOM.Iterable"],
    strictNullChecks: true,
    moduleResolution: tsModule.ModuleResolutionKind.NodeJs,
    esModuleInterop: true,
    noEmit: true,
    allowSyntheticDefaultImports: true,
    allowUnreachableCode: true,
    allowUnusedLabels: true,
    skipLibCheck: true
};
/**
 * Compiles an array of file paths using typescript.
 * @param filePaths
 * @param options
 */
function compileTypescript(filePaths, options = defaultOptions) {
    filePaths = Array.isArray(filePaths) ? filePaths : [filePaths];
    const program = tsModule.createProgram(filePaths, options);
    const files = program
        .getSourceFiles()
        .filter(sf => filePaths.includes(sf.fileName))
        .sort((sfA, sfB) => (sfA.fileName > sfB.fileName ? 1 : -1));
    return { program, files };
}

/**
 * Logs to the console with a specific level.
 * This function takes the config into account
 * @param text
 * @param config
 * @param level
 */
function log(text, config, level = "normal") {
    // Never log if silent
    if (config.silent) {
        return;
    }
    // Never log verbose if verbose is not on
    if (level === "verbose" && !config.verbose) {
        return;
    }
    // "unpack" function
    if (typeof text === "function") {
        text = text();
    }
    // eslint-disable-next-line no-console
    if (typeof text === "object") {
        // eslint-disable-next-line no-console
        console.dir(text, { depth: 10 });
    }
    else {
        // eslint-disable-next-line no-console
        console.log(text);
    }
}
/**
 * Logs only if verbose is set to true in the config
 * @param text
 * @param config
 */
function logVerbose(text, config) {
    log(text, config, "verbose");
}

const IGNORE_GLOBS = ["**/node_modules/**", "**/web_modules/**"];
const DEFAULT_DIR_GLOB = "**/*.{js,jsx,ts,tsx}";
const DEFAULT_GLOBS = [DEFAULT_DIR_GLOB];
/**
 * Parses and analyses all globs and calls some callbacks while doing it.
 * @param globs
 * @param config
 * @param context
 */
async function analyzeGlobs(globs, config, context = {}) {
    var _a, _b, _c;
    // Set default glob
    if (globs.length === 0) {
        globs = DEFAULT_GLOBS;
    }
    // Expand the globs
    const filePaths = await expandGlobs(globs, config);
    logVerbose(() => filePaths, config);
    // Callbacks
    (_a = context.didExpandGlobs) === null || _a === void 0 ? void 0 : _a.call(context, filePaths);
    (_b = context.willAnalyzeFiles) === null || _b === void 0 ? void 0 : _b.call(context, filePaths);
    // Parse all the files with typescript
    const { program, files } = compileTypescript(filePaths);
    // Analyze each file with web component analyzer
    const results = [];
    for (const file of files) {
        // Analyze
        const result = transformAnalyzerResult.analyzeSourceFile(file, {
            program,
            verbose: config.verbose || false,
            ts: config.ts,
            config: {
                features: config.features,
                analyzeDependencies: config.analyzeDependencies,
                analyzeDefaultLib: config.analyzeDefaultLibrary,
                analyzeGlobalFeatures: config.analyzeGlobalFeatures,
                analyzeAllDeclarations: config.format == "json2" // TODO: find a better way to construct the config
            }
        });
        logVerbose(() => transformAnalyzerResult.stripTypescriptValues(result, program.getTypeChecker()), config);
        // Callback
        await ((_c = context.emitAnalyzedFile) === null || _c === void 0 ? void 0 : _c.call(context, file, result, { program }));
        results.push(result);
    }
    return { program, files, results };
}
/**
 * Expands the globs.
 * @param globs
 * @param config
 */
async function expandGlobs(globs, config) {
    globs = Array.isArray(globs) ? globs : [globs];
    const ignoreGlobs = (config === null || config === void 0 ? void 0 : config.discoverNodeModules) ? [] : IGNORE_GLOBS;
    return transformAnalyzerResult.arrayFlat(await Promise.all(globs.map(g => {
        try {
            // Test if the glob points to a directory.
            // If so, return the result of a new glob that searches for files in the directory excluding node_modules..
            const dirExists = fs.existsSync(g) && fs.lstatSync(g).isDirectory();
            if (dirExists) {
                return fastGlob([fastGlobNormalize(`${g}/${DEFAULT_DIR_GLOB}`)], {
                    ignore: ignoreGlobs,
                    absolute: true,
                    followSymbolicLinks: false
                });
            }
        }
        catch (e) {
            // the glob wasn't a directory
        }
        // Return the result of globbing
        return fastGlob([fastGlobNormalize(g)], {
            ignore: ignoreGlobs,
            absolute: true,
            followSymbolicLinks: false
        });
    })));
}
/**
 * Fast glob recommends normalizing paths for windows, because fast glob expects a Unix-style path.
 * Read more here: https://github.com/mrmlnc/fast-glob#how-to-write-patterns-on-windows
 * @param glob
 */
function fastGlobNormalize(glob) {
    return glob.replace(/\\/g, "/");
}

const ERROR_NAME = "CLIError";
/**
 * Make an error of kind "CLIError"
 * Use this function instead of subclassing Error because of problems after transpilation.
 * @param message
 */
function makeCliError(message) {
    const error = new Error(message);
    error.name = ERROR_NAME;
    return error;
}
/**
 * Returns if an error is of kind "CLIError"
 * @param error
 */
function isCliError(error) {
    return error instanceof Error && error.name === ERROR_NAME;
}

function ensureDirSync(dir) {
    try {
        fs.mkdirSync(dir, { recursive: true });
    }
    catch (err) {
        if (err.code !== "EEXIST")
            throw err;
    }
}

/**
 * Runs the analyze cli command.
 * @param config
 */
const analyzeCliCommand = async (config) => {
    var _a;
    const inputGlobs = config.glob || [];
    // Log warning for experimental json format
    if (config.format === "json" || config.format === "json2" || ((_a = config.outFile) === null || _a === void 0 ? void 0 : _a.endsWith(".json"))) {
        log(`
!!!!!!!!!!!!!  WARNING !!!!!!!!!!!!!
The custom-elements.json format is for experimental purposes. You can expect changes to this format.
Please follow and contribute to the discussion at:		
  - https://github.com/webcomponents/custom-elements-json
  - https://github.com/w3c/webcomponents/issues/776
!!!!!!!!!!!!!  WARNING !!!!!!!!!!!!!
`, config);
    }
    // If no "out" is specified, output to console
    const outStrategy = (() => {
        if (config.outDir == null && config.outFile == null && config.outFiles == null) {
            switch (config.format) {
                case "json2":
                    // "json2" will need to output everything at once
                    return "console_bulk";
                default:
                    return "console_stream";
            }
        }
        return "file";
    })();
    // Give this context to the analyzer
    const context = {
        didExpandGlobs(filePaths) {
            if (filePaths.length === 0) {
                throw makeCliError(`Couldn't find any files to analyze.`);
            }
        },
        willAnalyzeFiles(filePaths) {
            log(`Web Component Analyzer analyzing ${filePaths.length} file${filePaths.length === 1 ? "" : "s"}...`, config);
        },
        emitAnalyzedFile(file, result, { program }) {
            // Emit the transformed results as soon as possible if "outConsole" is on
            if (outStrategy === "console_stream") {
                if (result.componentDefinitions.length > 0) {
                    // Always use "console.log" when outputting the results
                    /* eslint-disable-next-line no-console */
                    console.log(transformResults(result, program, { ...config, cwd: config.cwd || process.cwd() }));
                }
            }
        }
    };
    // Analyze, - all the magic happens in here
    const { results, program } = await analyzeGlobs(inputGlobs, config, context);
    const filteredResults = results.filter(result => { var _a; return result.componentDefinitions.length > 0 || result.globalFeatures != null || (((_a = result.declarations) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0; });
    // Write files to the file system
    if (outStrategy === "console_bulk") {
        // Always use "console.log" when outputting the results
        /* eslint-disable-next-line no-console */
        console.log(transformResults(filteredResults, program, { ...config, cwd: config.cwd || process.cwd() }));
    }
    else if (outStrategy === "file") {
        // Build up a map of "filePath => result[]"
        const outputResultMap = await distributeResultsIntoFiles(filteredResults, config);
        // Write all results to corresponding paths
        for (const [outputPath, results] of outputResultMap) {
            if (outputPath != null) {
                if (config.dry) {
                    const tagNames = transformAnalyzerResult.arrayFlat(results.map(result => result.componentDefinitions.map(d => d.tagName)));
                    log(`[dry] Intending to write ${tagNames} to ./${path.relative(process.cwd(), outputPath)}`, config);
                }
                else {
                    const content = transformResults(results, program, { ...config, cwd: config.cwd || path.dirname(outputPath) });
                    ensureDirSync(path.dirname(outputPath));
                    fs.writeFileSync(outputPath, content);
                }
            }
        }
    }
};
/**
 * Transforms analyze results based on the wca cli config.
 * @param results
 * @param program
 * @param config
 */
function transformResults(results, program, config) {
    var _a, _b;
    results = Array.isArray(results) ? results : [results];
    // Default format is "markdown"
    const format = config.format || "markdown";
    const transformerConfig = {
        inlineTypes: (_a = config.inlineTypes) !== null && _a !== void 0 ? _a : false,
        visibility: (_b = config.visibility) !== null && _b !== void 0 ? _b : "public",
        markdown: config.markdown,
        cwd: config.cwd
    };
    return transformAnalyzerResult.transformAnalyzerResult(format, results, program, transformerConfig);
}
/**
 * Analyzes input globs and returns the transformed result.
 * @param inputGlobs
 * @param config
 */
async function analyzeAndTransformGlobs(inputGlobs, config) {
    const { results, program } = await analyzeGlobs(Array.isArray(inputGlobs) ? inputGlobs : [inputGlobs], config);
    return transformResults(results, program, config);
}
/**
 * Distribute results into files and return a map of "path => results"
 * @param results
 * @param config
 */
async function distributeResultsIntoFiles(results, config) {
    const outputPathToResultMap = new Map();
    // Helper function to add a result to a path. It will merge into existing results.
    const addToOutputPath = (path, result) => {
        const existing = outputPathToResultMap.get(path) || [];
        existing.push(result);
        outputPathToResultMap.set(path, existing);
    };
    // Output files into directory
    if (config.outDir != null) {
        // Get extension name based on the specified format.
        const extName = formatToExtension(config.format || "markdown");
        for (const result of results) {
            // Write file to disc for each analyzed file
            const definition = result.componentDefinitions[0];
            if (definition == null)
                continue;
            // The name of the file becomes the tagName of the first component definition in the file.
            const path$1 = path.resolve(process.cwd(), config.outDir, `${definition.tagName}${extName}`);
            addToOutputPath(path$1, result);
        }
    }
    // Output all results into a single file
    else if (config.outFile != null) {
        // Guess format based on outFile extension
        // eslint-disable-next-line require-atomic-updates
        config.format = config.format || extensionToFormat(config.outFile);
        const path$1 = path.resolve(process.cwd(), config.outFile);
        for (const result of results) {
            addToOutputPath(path$1, result);
        }
    }
    // Output all results into multiple files
    else if (config.outFiles != null) {
        // Guess format based on outFile extension
        // eslint-disable-next-line require-atomic-updates
        config.format = config.format || extensionToFormat(config.outFiles);
        for (const result of results) {
            const dir = path.relative(process.cwd(), path.dirname(result.sourceFile.fileName));
            const filename = path.relative(process.cwd(), path.basename(result.sourceFile.fileName, path.extname(result.sourceFile.fileName)));
            for (const definition of result.componentDefinitions) {
                // The name of the file becomes the tagName of the first component definition in the file.
                const path$1 = path.resolve(process.cwd(), config
                    .outFiles.replace(/{dir}/g, dir)
                    .replace(/{filename}/g, filename)
                    .replace(/{tagname}/g, definition.tagName));
                //const path = resolve(process.cwd(), config.outFiles!, definition.tagName);
                addToOutputPath(path$1, {
                    sourceFile: result.sourceFile,
                    componentDefinitions: [definition]
                });
            }
        }
    }
    // Not "out" was specified. Add results to the special key "null"
    else {
        outputPathToResultMap.set(null, results);
    }
    return outputPathToResultMap;
}
/**
 * Returns an extension based on a format
 * @param kind
 */
function formatToExtension(kind) {
    switch (kind) {
        case "json":
        case "vscode":
            return ".json";
        case "md":
        case "markdown":
            return ".md";
        default:
            return ".txt";
    }
}
/**
 * Returns a format based on an extension
 * @param path
 */
function extensionToFormat(path$1) {
    const extName = path.extname(path$1);
    switch (extName) {
        case ".json":
            return "json";
        case ".md":
            return "markdown";
        default:
            return "markdown";
    }
}

/**
 * The main function of the cli.
 */
function cli() {
    const argv = yargs__namespace
        .usage("Usage: $0 <command> [glob..] [options]")
        .command({
        command: ["analyze [glob..]", "$0"],
        describe: "Analyses components and emits results in a specified format.",
        handler: async (config) => {
            try {
                await analyzeCliCommand(config);
            }
            catch (e) {
                if (isCliError(e)) {
                    log(e.message, config);
                }
                else {
                    throw e;
                }
            }
        }
    })
        .example(`$ $0 analyze`, "")
        .example(`$ $0 analyze src --format markdown`, "")
        .example(`$ $0 analyze "src/**/*.{js,ts}" --outDir output`, "")
        .example(`$ $0 analyze my-element.js --outFile custom-elements.json`, "")
        .example(`$ $0 analyze --outFiles {dir}/custom-element.json`, "")
        .option("outDir", {
        describe: `Output to a directory where each file corresponds to a web component`,
        nargs: 1,
        string: true
    })
        .option("outFile", {
        describe: `Concatenate and emit output to a single file`,
        nargs: 1,
        string: true
    })
        .option("outFiles", {
        describe: `Emit output to multiple files using a pattern. Available substitutions:
o {dir}: The directory of the component
o {filename}: The filename (without ext) of the component
o {tagname}: The element's tag name`,
        nargs: 1,
        string: true
    })
        .option("format", {
        describe: `Specify output format`,
        choices: ["md", "markdown", "json", "json2", "vscode"],
        nargs: 1,
        alias: "f"
    })
        .option("features", {
        describe: `Features to enable`,
        array: true,
        choices: ["member", "method", "cssproperty", "csspart", "event", "slot"]
    })
        .option("analyzeDefaultLibrary", {
        boolean: true,
        hidden: true
    })
        .option("analyzeDependencies", {
        boolean: true,
        hidden: true
    })
        .option("discoverNodeModules", {
        boolean: true,
        hidden: true
    })
        .option("visibility", {
        describe: `Minimum visibility`,
        choices: ["private", "protected", "public"]
    })
        .option("inlineTypes", {
        describe: `Inline type aliases`,
        boolean: true
    })
        .option("dry", {
        describe: `Don't write files`,
        boolean: true,
        alias: "d"
    })
        .option("verbose", {
        boolean: true,
        hidden: true
    })
        .option("silent", {
        boolean: true,
        hidden: true
    })
        // This options makes it possible to use "markdown.<sub-option>" in "strict mode"
        .option("markdown", {
        hidden: true
    })
        // This option makes it possible to specify a base cwd to use when emitting paths
        .option("cwd", {
        string: true,
        hidden: true
    })
        .alias("v", "version")
        .help("h")
        .wrap(110)
        .strict()
        .alias("h", "help").argv;
    if (argv.verbose) {
        /* eslint-disable-next-line no-console */
        console.log("CLI options:", argv);
    }
}

exports.analyzeAndTransformGlobs = analyzeAndTransformGlobs;
exports.analyzeCliCommand = analyzeCliCommand;
exports.cli = cli;
