"use strict";
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodexCliAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const toml_1 = require("@iarna/toml");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
const constants_1 = require("../constants");
/**
 * OpenAI Codex CLI agent adapter.
 */
class CodexCliAgent {
    constructor() {
        this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
    }
    getIdentifier() {
        return 'codex';
    }
    getName() {
        return 'OpenAI Codex CLI';
    }
    async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
        // First perform idempotent AGENTS.md write via composed AgentsMdAgent
        await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, {
            // Preserve explicit outputPath precedence semantics if provided.
            outputPath: agentConfig?.outputPath ||
                agentConfig?.outputPathInstructions ||
                undefined,
        }, backup);
        // Use proper path resolution from getDefaultOutputPath and agentConfig
        const defaults = this.getDefaultOutputPath(projectRoot);
        const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
        if (mcpEnabled && rulerMcpJson) {
            // Apply MCP server filtering and transformation
            const { filterMcpConfigForAgent } = await Promise.resolve().then(() => __importStar(require('../mcp/capabilities')));
            const filteredMcpConfig = filterMcpConfigForAgent(rulerMcpJson, this);
            if (!filteredMcpConfig) {
                return; // No compatible servers found
            }
            const filteredRulerMcpJson = filteredMcpConfig;
            // Determine the config file path using proper precedence
            const configPath = agentConfig?.outputPathConfig ?? defaults.config;
            // Ensure the parent directory exists
            await fs_1.promises.mkdir(path.dirname(configPath), { recursive: true });
            // Get the merge strategy
            const strategy = agentConfig?.mcp?.strategy ?? 'merge';
            // Extract MCP servers from filtered ruler config
            const rulerServers = filteredRulerMcpJson.mcpServers || {};
            // Read existing TOML config if it exists
            let existingConfig = {};
            try {
                const existingContent = await fs_1.promises.readFile(configPath, 'utf8');
                existingConfig = (0, toml_1.parse)(existingContent);
            }
            catch {
                // File doesn't exist or can't be parsed, use empty config
            }
            // Create the updated config
            const updatedConfig = { ...existingConfig };
            // Initialize mcp_servers if it doesn't exist
            if (!updatedConfig.mcp_servers) {
                updatedConfig.mcp_servers = {};
            }
            if (strategy === 'overwrite') {
                // For overwrite strategy, replace the entire mcp_servers section
                updatedConfig.mcp_servers = {};
            }
            // Add the ruler servers
            for (const [serverName, serverConfig] of Object.entries(rulerServers)) {
                // Create a properly formatted MCP server entry
                const mcpServer = {};
                if (serverConfig.command) {
                    mcpServer.command = serverConfig.command;
                }
                if (serverConfig.url) {
                    mcpServer.url = serverConfig.url;
                }
                if (serverConfig.args) {
                    mcpServer.args = serverConfig.args;
                }
                // Format env as an inline table
                if (serverConfig.env) {
                    mcpServer.env = serverConfig.env;
                }
                // Handle additional properties from remote server transformation
                if (serverConfig.headers) {
                    mcpServer.headers = serverConfig.headers;
                }
                if (updatedConfig.mcp_servers) {
                    updatedConfig.mcp_servers[serverName] = mcpServer;
                }
            }
            // Convert to TOML using structured objects
            const finalConfig = { ...updatedConfig };
            // @iarna/toml should handle the formatting properly
            const tomlContent = (0, toml_1.stringify)(finalConfig);
            await (0, FileSystemUtils_1.writeGeneratedFile)(configPath, tomlContent);
        }
    }
    getDefaultOutputPath(projectRoot) {
        return {
            instructions: path.join(projectRoot, constants_1.DEFAULT_RULES_FILENAME),
            config: path.join(projectRoot, '.codex', 'config.toml'),
        };
    }
    getMcpServerKey() {
        return 'mcp_servers';
    }
    supportsMcpStdio() {
        return true;
    }
    supportsMcpRemote() {
        return true;
    }
    supportsNativeSkills() {
        return true;
    }
}
exports.CodexCliAgent = CodexCliAgent;
