import path from "path";
import fs from "fs";
import prettier from "prettier";
import parserTypescript from "prettier/parser-typescript.js";
import { URL } from "url";
import load, { resolveSchema, VIRTUAL_JSON_URL } from "./load.js";
import { swaggerVersion } from "./utils.js";
import { transformAll } from "./transform/index.js";
import { makeApiPathsEnum } from "./transform/paths.js";
export * from "./types.js";
export const COMMENT_HEADER = `/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */


`;
async function openapiTS(schema, options = {}) {
    const ctx = {
        additionalProperties: options.additionalProperties || false,
        auth: options.auth,
        commentHeader: typeof options.commentHeader === "string" ? options.commentHeader : COMMENT_HEADER,
        defaultNonNullable: options.defaultNonNullable || false,
        formatter: options && typeof options.formatter === "function" ? options.formatter : undefined,
        immutableTypes: options.immutableTypes || false,
        contentNever: options.contentNever || false,
        makePathsEnum: options.makePathsEnum || false,
        pathParamsAsTypes: options.pathParamsAsTypes,
        rawSchema: options.rawSchema || false,
        supportArrayLength: options.supportArrayLength,
        version: options.version || 3,
    };
    const isInlineSchema = typeof schema != "string" && schema instanceof URL == false;
    let rootSchema = {};
    let external = {};
    const allSchemas = {};
    const schemaURL = typeof schema === "string" ? resolveSchema(schema) : schema;
    await load(schemaURL, {
        ...ctx,
        schemas: allSchemas,
        rootURL: isInlineSchema ? new URL(VIRTUAL_JSON_URL) : schemaURL,
        httpHeaders: options.httpHeaders,
        httpMethod: options.httpMethod,
    });
    for (const k of Object.keys(allSchemas)) {
        const rootSchemaID = isInlineSchema ? VIRTUAL_JSON_URL : schemaURL.href;
        if (k === rootSchemaID) {
            rootSchema = allSchemas[k];
        }
        else {
            external[k] = allSchemas[k];
        }
    }
    let output = ctx.commentHeader;
    if (!(options === null || options === void 0 ? void 0 : options.version) && !ctx.rawSchema)
        ctx.version = swaggerVersion(rootSchema);
    const rootTypes = transformAll(rootSchema, { ...ctx });
    const exportedKind = options.exportType === true ? "type" : "interface";
    const exportedKindOperator = options.exportType === true ? " =" : "";
    const exportedKindSemicolon = options.exportType === true ? ";" : "";
    for (const k of Object.keys(rootTypes)) {
        if (typeof rootTypes[k] === "string") {
            output += `export ${exportedKind} ${k}${exportedKindOperator} {\n  ${rootTypes[k]}\n}\n\n`;
        }
    }
    output += `export ${exportedKind} external${exportedKindOperator} {\n`;
    const externalKeys = Object.keys(external);
    externalKeys.sort((a, b) => a.localeCompare(b, "en", { numeric: true }));
    for (const subschemaURL of externalKeys) {
        output += `  "${subschemaURL}": {\n`;
        const subschemaTypes = transformAll(external[subschemaURL], { ...ctx, namespace: subschemaURL });
        for (const k of Object.keys(subschemaTypes)) {
            output += `    "${k}": {\n      ${subschemaTypes[k]}\n    }\n`;
        }
        output += `  }\n`;
    }
    output += `}${exportedKindSemicolon}\n\n`;
    if (ctx.makePathsEnum && rootSchema.paths)
        output += makeApiPathsEnum(rootSchema.paths);
    let prettierOptions = {
        parser: "typescript",
        plugins: [parserTypescript],
    };
    if (options && options.prettierConfig) {
        try {
            const prettierConfigFile = path.resolve(process.cwd(), options.prettierConfig);
            await fs.promises.access(prettierConfigFile, fs.constants.F_OK);
            const userOptions = await prettier.resolveConfig(prettierConfigFile);
            prettierOptions = {
                ...(userOptions || {}),
                ...prettierOptions,
                plugins: [...prettierOptions.plugins, ...((userOptions && userOptions.plugins) || [])],
            };
        }
        catch (err) {
            console.error(`❌ ${err}`);
            process.exit(1);
        }
    }
    return prettier.format(output, prettierOptions);
}
export default openapiTS;
//# sourceMappingURL=index.js.map