"use strict";
/**
 * Config Command Handler
 *
 * Launches web-based configuration dashboard.
 * Ensures CLIProxy service is running for dashboard features.
 * Usage: ccs config [--port PORT] [--host HOST] [--dev]
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleConfigCommand = void 0;
const get_port_1 = __importDefault(require("get-port"));
const open_1 = __importDefault(require("open"));
const web_server_1 = require("../web-server");
const shutdown_1 = require("../web-server/shutdown");
const service_manager_1 = require("../cliproxy/service-manager");
const port_manager_1 = require("../cliproxy/config/port-manager");
const supervisord_lifecycle_1 = require("../docker/supervisord-lifecycle");
const ui_1 = require("../utils/ui");
const named_command_router_1 = require("./named-command-router");
const config_dashboard_host_1 = require("./config-dashboard-host");
const config_command_options_1 = require("./config-command-options");
const logging_1 = require("../services/logging");
const config_loader_facade_1 = require("../config/config-loader-facade");
const logger = (0, logging_1.createLogger)('command:config');
const CONFIG_SUBCOMMAND_ROUTES = [
    {
        name: 'channels',
        handle: async (args) => {
            const { handleConfigChannelsCommand } = await Promise.resolve().then(() => __importStar(require('./config-channels-command')));
            await handleConfigChannelsCommand(args);
        },
    },
    {
        name: 'auth',
        handle: async (args) => {
            const { handleConfigAuthCommand } = await Promise.resolve().then(() => __importStar(require('./config-auth')));
            await handleConfigAuthCommand(args);
        },
    },
    {
        name: 'image-analysis',
        handle: async (args) => {
            const { handleConfigImageAnalysisCommand } = await Promise.resolve().then(() => __importStar(require('./config-image-analysis-command')));
            await handleConfigImageAnalysisCommand(args);
        },
    },
    {
        name: 'thinking',
        handle: async (args) => {
            const { handleConfigThinkingCommand } = await Promise.resolve().then(() => __importStar(require('./config-thinking-command')));
            await handleConfigThinkingCommand(args);
        },
    },
];
const defaultConfigCommandDependencies = {
    getPort: get_port_1.default,
    openBrowser: open_1.default,
    startServer: web_server_1.startServer,
    setupGracefulShutdown: shutdown_1.setupGracefulShutdown,
    ensureCliproxyService: service_manager_1.ensureCliproxyService,
    isRunningUnderSupervisord: supervisord_lifecycle_1.isRunningUnderSupervisord,
    getDashboardAuthConfig: config_loader_facade_1.getDashboardAuthConfig,
    initUI: ui_1.initUI,
    header: ui_1.header,
    ok: ui_1.ok,
    info: ui_1.info,
    warn: ui_1.warn,
    fail: ui_1.fail,
    resolveNamedCommand: named_command_router_1.resolveNamedCommand,
    configSubcommandRoutes: CONFIG_SUBCOMMAND_ROUTES,
};
/**
 * Handle config command
 */
async function handleConfigCommand(args, deps = defaultConfigCommandDependencies) {
    if (args.length === 1 && args[0] === 'help') {
        await deps.initUI();
        (0, config_command_options_1.showConfigCommandHelp)();
        process.exit(0);
    }
    const subcommand = args[0]?.startsWith('-')
        ? undefined
        : deps.resolveNamedCommand(args[0], deps.configSubcommandRoutes);
    if (subcommand) {
        await subcommand.handle(args.slice(1));
        return;
    }
    await deps.initUI();
    const parsed = (0, config_command_options_1.parseConfigCommandArgs)(args);
    if (parsed.help) {
        (0, config_command_options_1.showConfigCommandHelp)();
        process.exit(0);
    }
    if (parsed.error) {
        console.error(deps.fail(parsed.error));
        process.exit(1);
    }
    const options = parsed.options;
    const verbose = options.dev;
    logger.info('dashboard.launch_requested', 'Config dashboard launch requested', {
        dev: Boolean(options.dev),
        host: options.host || null,
        port: options.port || null,
    });
    console.log(deps.header('CCS Config Dashboard'));
    console.log('');
    const lifecyclePort = (0, port_manager_1.resolveLifecyclePort)();
    if (deps.isRunningUnderSupervisord?.() ?? false) {
        logger.info('cliproxy.supervisord_managed', 'Skipping direct CLIProxy startup in Docker', {
            port: lifecyclePort,
        });
        console.log(deps.info(`CLIProxy is managed by supervisord on port ${lifecyclePort}`));
    }
    else {
        // Ensure CLIProxy service is running for dashboard features
        console.log(deps.info('Starting CLIProxy service...'));
        const cliproxyResult = await deps.ensureCliproxyService(lifecyclePort, verbose);
        logger.info('cliproxy.ensure_result', 'Config command checked CLIProxy availability', {
            started: cliproxyResult.started,
            alreadyRunning: cliproxyResult.alreadyRunning,
            configRegenerated: cliproxyResult.configRegenerated,
            port: cliproxyResult.port || null,
            error: cliproxyResult.error || null,
        });
        if (cliproxyResult.started) {
            if (cliproxyResult.alreadyRunning) {
                console.log(deps.ok(`CLIProxy already running on port ${cliproxyResult.port}`));
                if (cliproxyResult.configRegenerated) {
                    console.log(deps.warn('Config updated - restart CLIProxy to apply changes'));
                }
            }
            else {
                console.log(deps.ok(`CLIProxy started on port ${cliproxyResult.port}`));
            }
        }
        else {
            console.log(deps.warn(`CLIProxy not available: ${cliproxyResult.error}`));
            console.log(deps.info('Dashboard will work but Control Panel/Stats may be limited'));
        }
    }
    console.log('');
    console.log(deps.info('Starting dashboard server...'));
    // Find available port
    const port = options.port ??
        (await deps.getPort({
            port: [3000, 3001, 3002, 8000, 8080],
        }));
    try {
        // Start server
        const serverOptions = {
            port,
            dev: options.dev,
        };
        if (options.host) {
            serverOptions.host = (0, config_dashboard_host_1.normalizeDashboardHost)(options.host);
        }
        const { server, wss, cleanup } = await deps.startServer(serverOptions);
        // Setup graceful shutdown
        deps.setupGracefulShutdown(server, wss, cleanup);
        const urls = (0, config_dashboard_host_1.resolveDashboardUrls)(resolveServerBindHost(server) ?? options.host, port);
        const shouldWarnAboutExposure = urls.bindHost ? !(0, config_dashboard_host_1.isLoopbackHost)(urls.bindHost) : false;
        if (options.dev) {
            console.log(deps.ok(`Dev Server: ${urls.browserUrl}`));
            console.log('');
            console.log(deps.info('HMR enabled - UI changes will hot-reload'));
        }
        else {
            console.log(deps.ok(`Dashboard: ${urls.browserUrl}`));
        }
        if (shouldWarnAboutExposure && urls.bindHost) {
            console.log(deps.info(`Bind host: ${urls.bindHost}`));
            if (urls.networkUrls?.length === 1) {
                console.log(deps.info(`Network URL: ${urls.networkUrls[0]}`));
            }
            else if (urls.networkUrls && urls.networkUrls.length > 1) {
                console.log(deps.info('Network URLs:'));
                for (const networkUrl of urls.networkUrls) {
                    console.log(deps.info(`  ${networkUrl}`));
                }
            }
        }
        if (shouldWarnAboutExposure && urls.bindHost) {
            const authConfig = deps.getDashboardAuthConfig();
            console.log(deps.warn('Dashboard may be reachable from other devices that can connect to this machine.'));
            if (!authConfig.enabled) {
                console.log(deps.info('Protect it before sharing: ccs config auth setup'));
            }
            if ((0, config_dashboard_host_1.isWildcardHost)(urls.bindHost) && !urls.networkUrls?.length) {
                console.log(deps.info('Use your machine IP or hostname from the other device.'));
            }
        }
        console.log('');
        // Open browser
        try {
            await deps.openBrowser(urls.browserUrl, { wait: false });
            logger.info('dashboard.browser_opened', 'Config dashboard browser launch attempted', {
                browserUrl: urls.browserUrl,
            });
            console.log(deps.info('Browser opened automatically'));
        }
        catch {
            logger.warn('dashboard.browser_open_failed', 'Automatic browser launch failed', {
                browserUrl: urls.browserUrl,
            });
            console.log(deps.info(`Open manually: ${urls.browserUrl}`));
        }
        console.log('');
        console.log(deps.info('Press Ctrl+C to stop'));
    }
    catch (error) {
        logger.error('dashboard.launch_failed', 'Config dashboard failed to launch', {
            message: error.message,
        });
        console.error(deps.fail(`Failed to start server: ${error.message}`));
        process.exit(1);
    }
}
exports.handleConfigCommand = handleConfigCommand;
function resolveServerBindHost(server) {
    const address = server.address();
    if (!address || typeof address === 'string') {
        return undefined;
    }
    return address.address;
}
//# sourceMappingURL=config-command.js.map