import fs from "node:fs";
import path from "node:path";
import { convertDocument, detectFormatFromExtension, generateOutputPath, } from "@zuplo/openapi-tools";
import chokidar from "chokidar";
import { logger } from "../../common/logger.js";
import { printDiagnosticsToConsole } from "../../common/output.js";
async function performConversion(args) {
    const inputPath = path.resolve(args.input);
    const outputPath = args.output ? path.resolve(args.output) : undefined;
    const { format, json, yaml } = args;
    let outputFormat;
    if (format) {
        outputFormat = format;
    }
    else if (json) {
        outputFormat = "json";
    }
    else if (yaml) {
        outputFormat = "yaml";
    }
    else {
        throw new Error("Output format must be specified using --format, --json, or --yaml");
    }
    const inputFormat = detectFormatFromExtension(inputPath);
    if (!inputFormat) {
        throw new Error(`Unable to determine input format from extension: ${path.extname(inputPath)}`);
    }
    if (inputFormat === outputFormat) {
        if (!args.watch) {
            printDiagnosticsToConsole(`Input file is already in ${outputFormat.toUpperCase()} format. No conversion needed.`);
        }
        return;
    }
    if (!args.watch) {
        printDiagnosticsToConsole("OpenAPI Format Converter");
        printDiagnosticsToConsole("========================");
        printDiagnosticsToConsole(`Input file:    ${inputPath}`);
        printDiagnosticsToConsole(`Input format:  ${inputFormat.toUpperCase()}`);
        printDiagnosticsToConsole(`Output format: ${outputFormat.toUpperCase()}`);
        if (outputPath) {
            printDiagnosticsToConsole(`Output file:   ${outputPath}`);
        }
    }
    try {
        const inputContent = fs.readFileSync(inputPath, "utf-8");
        const { content: outputContent } = convertDocument(inputContent, inputFormat, outputFormat);
        const finalOutputPath = outputPath || generateOutputPath(inputPath, outputFormat);
        const outputDir = path.dirname(finalOutputPath);
        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });
        }
        fs.writeFileSync(finalOutputPath, outputContent, "utf-8");
        if (!args.watch) {
            printDiagnosticsToConsole(`\n✓ Converted file written to: ${finalOutputPath}`);
        }
        else {
            printDiagnosticsToConsole(`✓ Converted file written to: ${finalOutputPath}`);
        }
    }
    catch (error) {
        logger.error(error, "Error converting OpenAPI file");
        printDiagnosticsToConsole(`Error: ${error.message}`);
        throw error;
    }
}
export async function convertOpenAPI(args) {
    if (!args.watch) {
        return performConversion(args);
    }
    const inputPath = path.resolve(args.input);
    if (!fs.existsSync(inputPath)) {
        throw new Error(`Input file not found: ${inputPath}`);
    }
    printDiagnosticsToConsole("OpenAPI Format Converter (Watch Mode)");
    printDiagnosticsToConsole("======================================");
    printDiagnosticsToConsole(`Input file: ${inputPath}`);
    printDiagnosticsToConsole("\nStarting watch mode...");
    printDiagnosticsToConsole("Press Ctrl+C to stop watching.\n");
    try {
        await performConversion(args);
        printDiagnosticsToConsole("\nWatching for changes...");
    }
    catch (error) {
        logger.error(error, "Initial conversion failed");
        printDiagnosticsToConsole(`Error during initial conversion: ${error}`);
        printDiagnosticsToConsole("\nWatching for changes...");
    }
    const watcher = chokidar.watch(inputPath, {
        persistent: true,
        ignoreInitial: true,
    });
    watcher.on("change", async () => {
        try {
            const relativePath = path.relative(process.cwd(), inputPath);
            printDiagnosticsToConsole(`\nFile ${relativePath} changed, re-converting...`);
            await performConversion(args);
            printDiagnosticsToConsole("Re-conversion completed successfully.\n");
        }
        catch (error) {
            logger.error(error, "Re-conversion failed");
            printDiagnosticsToConsole(`Error during re-conversion: ${error}\n`);
        }
    });
    watcher.on("error", (error) => {
        logger.error(error, "Watcher error");
        printDiagnosticsToConsole(`Watcher error: ${error}`);
    });
    return new Promise((resolve) => {
        process.once("SIGINT", async () => {
            printDiagnosticsToConsole("\nStopping watch mode...");
            await watcher.close();
            resolve();
        });
        process.once("SIGTERM", async () => {
            printDiagnosticsToConsole("\nStopping watch mode...");
            await watcher.close();
            resolve();
        });
    });
}
//# sourceMappingURL=handler.js.map