"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSConfigReader = void 0;
const path_1 = require("path");
const fs_1 = require("fs");
const ts = require("typescript");
const fs_2 = require("../../fs");
const assert_1 = require("assert");
function isFile(file) {
    return (0, fs_1.existsSync)(file) && (0, fs_1.statSync)(file).isFile();
}
function isDir(path) {
    return (0, fs_1.existsSync)(path) && (0, fs_1.statSync)(path).isDirectory();
}
class TSConfigReader {
    constructor() {
        /**
         * Note: Runs after the {@link TypeDocReader}.
         */
        this.priority = 200;
        this.name = "tsconfig-json";
    }
    /**
     * Not considered part of the public API. You can use it, but it might break.
     * @internal
     */
    static findConfigFile(file) {
        let fileToRead = file;
        if (isDir(fileToRead)) {
            fileToRead = ts.findConfigFile(file, isFile);
        }
        if (!fileToRead || !isFile(fileToRead)) {
            return;
        }
        return fileToRead;
    }
    read(container, logger) {
        var _a, _b;
        const file = container.getValue("tsconfig");
        let fileToRead = TSConfigReader.findConfigFile(file);
        if (!fileToRead) {
            // If the user didn't give us this option, we shouldn't complain about not being able to find it.
            if (container.isSet("tsconfig")) {
                logger.error(`The tsconfig file ${file} does not exist`);
            }
            return;
        }
        fileToRead = (0, fs_2.normalizePath)((0, path_1.resolve)(fileToRead));
        let fatalError = false;
        const parsed = ts.getParsedCommandLineOfConfigFile(fileToRead, {}, {
            ...ts.sys,
            onUnRecoverableConfigFileDiagnostic(error) {
                logger.diagnostic(error);
                fatalError = true;
            },
        });
        if (!parsed || fatalError) {
            return;
        }
        logger.diagnostics(parsed.errors);
        const typedocOptions = (_b = (_a = parsed.raw) === null || _a === void 0 ? void 0 : _a.typedocOptions) !== null && _b !== void 0 ? _b : {};
        if (typedocOptions.options) {
            logger.error([
                "typedocOptions in tsconfig file specifies an option file to read but the option",
                "file has already been read. This is likely a misconfiguration.",
            ].join(" "));
            delete typedocOptions.options;
        }
        if (typedocOptions.tsconfig) {
            logger.error("typedocOptions in tsconfig file may not specify a tsconfig file to read");
            delete typedocOptions.tsconfig;
        }
        container.setCompilerOptions(parsed.fileNames, parsed.options, parsed.projectReferences);
        for (const [key, val] of Object.entries(typedocOptions || {})) {
            try {
                // We catch the error, so can ignore the strict type checks
                container.setValue(key, val, (0, path_1.join)(fileToRead, ".."));
            }
            catch (error) {
                (0, assert_1.ok)(error instanceof Error);
                logger.error(error.message);
            }
        }
    }
}
exports.TSConfigReader = TSConfigReader;
