"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.createWorkflowServer = createWorkflowServer;
exports.getWorkflowServer = getWorkflowServer;
exports.stopWorkflowServer = stopWorkflowServer;
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const zod_1 = require("zod");
const defaults_1 = require("../../modules/defaults");
const logger_1 = require("../../lib/logger");
const yamlDb = __importStar(require("../../services/yaml-workflow/db"));
const yamlDeployer = __importStar(require("../../services/yaml-workflow/deployer"));
let server = null;
// ── Schemas ─────────────────────────────────────────────────────────────────
const listWorkflowsSchema = zod_1.z.object({
    status: zod_1.z.enum(['active', 'deployed', 'draft', 'archived']).optional()
        .describe('Filter by lifecycle status. Defaults to "active" (ready to invoke).'),
});
const invokeWorkflowSchema = zod_1.z.object({
    workflow_name: zod_1.z.string()
        .describe('Name of the compiled workflow to invoke (from list_workflows)'),
    input: zod_1.z.record(zod_1.z.any()).optional().default({})
        .describe('Input data matching the workflow input schema'),
    async: zod_1.z.boolean().optional().default(false)
        .describe('If true, fire-and-forget (returns job ID). If false, wait for result.'),
    timeout: zod_1.z.number().optional()
        .describe('Max milliseconds to wait for result (sync mode only). Default: 120000.'),
});
const getWorkflowSchema = zod_1.z.object({
    workflow_name: zod_1.z.string()
        .describe('Name of the workflow to inspect'),
});
/**
 * Create the Long Tail MCP Workflows server.
 *
 * Exposes compiled YAML workflows — hardened, deterministic pipelines
 * that were originally discovered through dynamic MCP triage — as
 * invocable MCP tools.
 *
 * Tools:
 * - list_workflows — discover available compiled workflows
 * - get_workflow — inspect a workflow's schema and activity manifest
 * - invoke_workflow — run a workflow (sync or async)
 */
async function createWorkflowServer(options) {
    if (server)
        return server;
    const name = options?.name || 'mcp-workflows-longtail';
    server = new mcp_js_1.McpServer({ name, version: '1.0.0' });
    // ── list_workflows ──────────────────────────────────────────────────
    server.registerTool('list_workflows', {
        title: 'List Compiled Workflows',
        description: 'List available compiled YAML workflows. These are deterministic pipelines ' +
            'converted from successful MCP triage executions. Each workflow represents ' +
            'a proven solution to a specific edge case (e.g., rotate-and-extract for ' +
            'upside-down documents). Defaults to listing active (invocable) workflows.',
        inputSchema: listWorkflowsSchema,
    }, async (args) => {
        const { workflows } = await yamlDb.listYamlWorkflows({
            status: args.status || 'active',
            limit: defaults_1.QUERY_LIMIT_MAX,
        });
        const items = workflows.map((wf) => ({
            name: wf.name,
            description: wf.description,
            tags: wf.tags,
            graph_topic: wf.graph_topic,
            source_workflow_type: wf.source_workflow_type,
            input_schema: wf.input_schema,
            output_schema: wf.output_schema,
            activity_count: wf.activity_manifest.filter((a) => a.type === 'worker').length,
            status: wf.status,
            activated_at: wf.activated_at,
        }));
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({ count: items.length, workflows: items }),
                }],
        };
    });
    // ── get_workflow ─────────────────────────────────────────────────────
    server.registerTool('get_workflow', {
        title: 'Get Workflow Details',
        description: 'Inspect a compiled workflow by name. Returns the full activity manifest, ' +
            'input/output schemas, and provenance (which execution it was compiled from).',
        inputSchema: getWorkflowSchema,
    }, async (args) => {
        const wf = await yamlDb.getYamlWorkflowByName(args.workflow_name);
        if (!wf) {
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({ error: `Workflow "${args.workflow_name}" not found` }),
                    }],
                isError: true,
            };
        }
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({
                        name: wf.name,
                        description: wf.description,
                        app_id: wf.app_id,
                        graph_topic: wf.graph_topic,
                        status: wf.status,
                        source_workflow_id: wf.source_workflow_id,
                        source_workflow_type: wf.source_workflow_type,
                        input_schema: wf.input_schema,
                        output_schema: wf.output_schema,
                        activities: wf.activity_manifest.filter((a) => a.type === 'worker').map((a) => ({
                            title: a.title,
                            tool_source: a.tool_source,
                            mcp_server_id: a.mcp_server_id,
                            mcp_tool_name: a.mcp_tool_name,
                        })),
                        activated_at: wf.activated_at,
                        created_at: wf.created_at,
                    }),
                }],
        };
    });
    // ── invoke_workflow ──────────────────────────────────────────────────
    server.registerTool('invoke_workflow', {
        title: 'Invoke Compiled Workflow',
        description: 'Run a compiled YAML workflow by name. These are deterministic pipelines — ' +
            'no LLM reasoning, just direct tool-to-tool data piping. Use list_workflows ' +
            'to discover available workflows and their input schemas. ' +
            'Set async=true for fire-and-forget (returns job ID), or leave false to wait for the result.',
        inputSchema: invokeWorkflowSchema,
    }, async (args) => {
        const wf = await yamlDb.getYamlWorkflowByName(args.workflow_name);
        if (!wf) {
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({ error: `Workflow "${args.workflow_name}" not found` }),
                    }],
                isError: true,
            };
        }
        if (wf.status !== 'active') {
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({
                            error: `Workflow "${args.workflow_name}" is not active (status: ${wf.status})`,
                        }),
                    }],
                isError: true,
            };
        }
        if (args.async) {
            const jobId = await yamlDeployer.invokeYamlWorkflow(wf.app_id, wf.graph_topic, args.input || {}, wf.graph_topic);
            return {
                content: [{
                        type: 'text',
                        text: JSON.stringify({
                            job_id: jobId,
                            workflow: wf.name,
                            status: 'started',
                        }),
                    }],
            };
        }
        const { job_id, result } = await yamlDeployer.invokeYamlWorkflowSync(wf.app_id, wf.graph_topic, args.input || {}, args.timeout, wf.graph_topic);
        return {
            content: [{
                    type: 'text',
                    text: JSON.stringify({
                        job_id,
                        namespace: wf.app_id,
                        workflow: wf.name,
                        status: 'completed',
                        result,
                    }),
                }],
        };
    });
    const toolCount = 3;
    logger_1.loggerRegistry.info(`[lt-mcp:server] ${name} ready (${toolCount} tools registered)`);
    return server;
}
/**
 * Get the current workflow MCP server instance.
 */
function getWorkflowServer() {
    return server;
}
/**
 * Stop the workflow MCP server.
 */
async function stopWorkflowServer() {
    if (server) {
        await server.close?.();
        server = null;
    }
}
