"use strict";
/**
 * CLIProxy Server Routes - API endpoints for proxy configuration
 *
 * Provides REST endpoints for managing CLIProxyAPI connection settings:
 * - GET /api/cliproxy-server - Get proxy configuration
 * - PUT /api/cliproxy-server - Update proxy configuration
 * - POST /api/cliproxy-server/test - Test remote connection
 */
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const remote_proxy_client_1 = require("../../cliproxy/services/remote-proxy-client");
const proxy_lifecycle_service_1 = require("../../cliproxy/services/proxy-lifecycle-service");
const platform_detector_1 = require("../../cliproxy/binary/platform-detector");
const port_manager_1 = require("../../cliproxy/config/port-manager");
const unified_config_types_1 = require("../../config/unified-config-types");
const provider_capabilities_1 = require("../../cliproxy/provider-capabilities");
const generator_1 = require("../../cliproxy/config/generator");
const auth_middleware_1 = require("../middleware/auth-middleware");
const config_loader_facade_1 = require("../../config/config-loader-facade");
const router = (0, express_1.Router)();
router.use((req, res, next) => {
    if ((0, auth_middleware_1.requireLocalAccessWhenAuthDisabled)(req, res, 'CLIProxy server endpoints require localhost access when dashboard auth is disabled.')) {
        next();
    }
});
/**
 * GET /api/cliproxy-server - Get proxy configuration
 */
router.get('/', async (_req, res) => {
    try {
        const config = await (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
        res.json(config.cliproxy_server || unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG);
    }
    catch (error) {
        console.error('[cliproxy-server-routes] Failed to load proxy config:', error);
        res.status(500).json({ error: 'Failed to load proxy config' });
    }
});
/**
 * PUT /api/cliproxy-server - Update proxy configuration
 */
router.put('/', (req, res) => {
    try {
        const updates = req.body;
        const currentConfig = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
        const currentLocalPort = (0, port_manager_1.validatePort)(currentConfig.cliproxy_server?.local?.port ?? unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG.local.port);
        const requestedLocalPort = updates.local?.port;
        if (requestedLocalPort !== undefined &&
            (!Number.isInteger(requestedLocalPort) ||
                requestedLocalPort < 1 ||
                requestedLocalPort > 65535)) {
            res.status(400).json({
                error: 'Invalid local port. Must be an integer between 1 and 65535.',
            });
            return;
        }
        const nextLocalPort = requestedLocalPort === undefined ? currentLocalPort : (0, port_manager_1.validatePort)(requestedLocalPort);
        if (nextLocalPort !== currentLocalPort && (0, proxy_lifecycle_service_1.isProxyRunning)()) {
            res.status(409).json({
                error: 'Proxy is running on the current local port. Stop CLIProxy before changing local.port.',
                proxyRunning: true,
                currentLocalPort,
            });
            return;
        }
        // Atomic read-modify-write — avoids race between load and save
        const updated = (0, config_loader_facade_1.mutateConfig)((config) => {
            config.cliproxy_server = {
                remote: {
                    ...unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG.remote,
                    ...config.cliproxy_server?.remote,
                    ...updates.remote,
                },
                fallback: {
                    ...unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG.fallback,
                    ...config.cliproxy_server?.fallback,
                    ...updates.fallback,
                },
                local: {
                    ...unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG.local,
                    ...config.cliproxy_server?.local,
                    ...updates.local,
                },
            };
        });
        res.json(updated.cliproxy_server);
    }
    catch (error) {
        console.error('[cliproxy-server-routes] Failed to save proxy config:', error);
        res.status(500).json({ error: 'Failed to save proxy config' });
    }
});
/**
 * GET /api/cliproxy-server/backend - Get CLIProxy backend setting
 * @returns {{ backend: 'original' | 'plus', managementPanelRepository: string }} Current backend configuration
 */
router.get('/backend', async (_req, res) => {
    try {
        const config = await (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
        res.json({
            backend: config.cliproxy?.backend ?? platform_detector_1.DEFAULT_BACKEND,
            managementPanelRepository: (0, generator_1.getManagementPanelRepository)(),
        });
    }
    catch (error) {
        console.error('[cliproxy-server-routes] Failed to load backend config:', error);
        res.status(500).json({ error: 'Failed to load backend config' });
    }
});
/**
 * PUT /api/cliproxy-server/backend - Update CLIProxy backend setting
 * @param {Object} req.body - Request body
 * @param {'original' | 'plus'} req.body.backend - Backend to switch to
 * @param {boolean} [req.body.force=false] - Force change even if proxy is running
 * @returns {{ backend: 'original' | 'plus', managementPanelRepository: string }} Updated backend configuration
 * @throws {400} Invalid backend value
 * @throws {409} Proxy is running (unless force=true)
 */
router.put('/backend', (req, res) => {
    try {
        const { backend, force } = req.body;
        if (backend !== 'original' && backend !== 'plus') {
            res.status(400).json({ error: 'Invalid backend. Must be "original" or "plus"' });
            return;
        }
        // Pre-flight read: check running state before acquiring write lock
        const currentConfig = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
        const currentBackend = currentConfig.cliproxy?.backend ?? platform_detector_1.DEFAULT_BACKEND;
        const localPort = (0, port_manager_1.validatePort)(currentConfig.cliproxy_server?.local?.port ?? unified_config_types_1.DEFAULT_CLIPROXY_SERVER_CONFIG.local.port);
        if (currentBackend !== backend && (0, proxy_lifecycle_service_1.isProxyRunning)() && !force) {
            res.status(409).json({
                error: 'Proxy is running. Stop proxy first or use force=true to change backend.',
                proxyRunning: true,
                currentBackend,
            });
            return;
        }
        // Atomic write — avoids race between load and save
        (0, config_loader_facade_1.mutateConfig)((config) => {
            if (!config.cliproxy) {
                config.cliproxy = {
                    backend,
                    oauth_accounts: {},
                    providers: [...provider_capabilities_1.CLIPROXY_PROVIDER_IDS],
                    variants: {},
                };
            }
            else {
                config.cliproxy.backend = backend;
            }
        });
        if ((0, generator_1.configNeedsRegeneration)(localPort)) {
            (0, generator_1.regenerateConfig)(localPort);
        }
        res.json({ backend, managementPanelRepository: (0, generator_1.getManagementPanelRepository)() });
    }
    catch (error) {
        console.error('[cliproxy-server-routes] Failed to save backend config:', error);
        res.status(500).json({ error: 'Failed to save backend config' });
    }
});
/**
 * POST /api/cliproxy-server/test - Test remote proxy connection
 */
router.post('/test', async (req, res) => {
    try {
        const { host, port, protocol, authToken, allowSelfSigned } = req.body;
        // Host is required, port is optional (uses protocol defaults)
        if (!host) {
            res.status(400).json({ error: 'Host is required' });
            return;
        }
        // Parse port - treat empty string, 0, null as "use default"
        const parsedPort = port && port !== '' ? parseInt(String(port), 10) : undefined;
        const effectivePort = parsedPort && !isNaN(parsedPort) && parsedPort > 0 ? parsedPort : undefined;
        const status = await (0, remote_proxy_client_1.testConnection)({
            host,
            port: effectivePort,
            protocol: protocol || 'http',
            authToken,
            allowSelfSigned: allowSelfSigned || false,
            timeout: 5000,
        });
        res.json(status);
    }
    catch (error) {
        console.error('[cliproxy-server-routes] Failed to test connection:', error);
        res.status(500).json({ error: 'Failed to test connection' });
    }
});
exports.default = router;
//# sourceMappingURL=proxy-routes.js.map