"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runWorkflowCommand = runWorkflowCommand;
exports.formatWorkflowTemplateReferenceUsages = formatWorkflowTemplateReferenceUsages;
const control_plane_config_1 = require("../config/control-plane-config");
const catalog_1 = require("../i18n/catalog");
const required_skills_1 = require("../workflows/required-skills");
const required_mcp_1 = require("../workflows/required-mcp");
const required_capability_intersection_1 = require("../workflows/required-capability-intersection");
const required_capability_reports_1 = require("../workflows/required-capability-reports");
const template_inventory_1 = require("../workflows/template-inventory");
const template_registry_1 = require("../workflows/template-registry");
const template_reference_usages_1 = require("../workflows/template-reference-usages");
const types_1 = require("../workflows/types");
const validation_1 = require("../workflows/validation");
const json_output_1 = require("./json-output");
const workflow_create_1 = require("./workflow-create");
const workflow_delete_1 = require("./workflow-delete");
const workflow_update_1 = require("./workflow-update");
async function runWorkflowCommand(cwd, args, locale) {
    switch (args.action) {
        case "create":
            return (0, workflow_create_1.runWorkflowCreateCommand)(cwd, args, locale);
        case "update":
            return (0, workflow_update_1.runWorkflowUpdateCommand)(cwd, args, locale);
        case "delete":
            return (0, workflow_delete_1.runWorkflowDeleteCommand)(cwd, args, locale);
        case "lint":
            return runWorkflowLintCommand(cwd, args, locale);
        case "list":
            return runWorkflowListCommand(cwd, args, locale);
    }
}
async function runWorkflowListCommand(cwd, args, locale) {
    let catalog;
    try {
        catalog = await (0, template_registry_1.loadWorkflowTemplates)((0, template_registry_1.getWorkflowTemplatesDirectoryPath)(cwd), locale);
    }
    catch (error) {
        console.log(error instanceof Error
            ? error.message
            : (0, catalog_1.translate)(locale, "workflow.runContext.catalogLoadFailed"));
        return 1;
    }
    const candidates = (0, template_inventory_1.buildWorkflowTemplateCandidates)(catalog, {
        ...(args.target !== undefined ? { target: args.target } : {}),
        includeSystem: args.includeSystem,
    });
    if (args.format === "json") {
        if (args.referencesTo !== undefined) {
            return runWorkflowListReferencesCommand({
                cwd,
                args,
                catalog,
                locale,
            });
        }
        (0, json_output_1.printCommandJson)(candidates.map(toWorkflowListJsonItem));
        return 0;
    }
    if (args.referencesTo !== undefined) {
        return runWorkflowListReferencesCommand({
            cwd,
            args,
            catalog,
            locale,
        });
    }
    const hiddenSystemCandidateCount = args.includeSystem
        ? 0
        : (0, template_inventory_1.buildWorkflowTemplateCandidates)(catalog, {
            ...(args.target !== undefined ? { target: args.target } : {}),
            includeSystem: true,
        }).filter((candidate) => candidate.system).length;
    console.log(formatWorkflowTemplateCandidates(candidates, locale, {
        hiddenSystemCandidateCount,
    }));
    return 0;
}
async function runWorkflowListReferencesCommand(input) {
    const targetPath = (0, template_reference_usages_1.normalizeWorkflowTemplateReferenceTargetPath)(input.args.referencesTo ?? "");
    if (targetPath === null) {
        console.log((0, catalog_1.translate)(input.locale, "workflow.command.template.invalidPath", {
            value: input.args.referencesTo ?? "",
        }));
        return 1;
    }
    const config = await (0, control_plane_config_1.loadConfig)(input.cwd).catch(() => null);
    const usages = (0, template_reference_usages_1.collectWorkflowTemplateReferenceUsages)({
        catalog: input.catalog,
        targetPath,
        includeSystemSources: true,
        config,
    });
    if (input.args.format === "json") {
        (0, json_output_1.printCommandJson)(usages.map(toWorkflowReferenceUsageJsonItem));
        return 0;
    }
    console.log(formatWorkflowTemplateReferenceUsages(usages, input.locale, targetPath));
    return 0;
}
function toWorkflowReferenceUsageJsonItem(usage) {
    return {
        targetPath: usage.targetPath,
        usageKind: usage.usageKind,
        sourceType: usage.sourceType,
        sourcePath: usage.sourcePath,
        lineNumber: usage.lineNumber,
        editable: usage.editable,
        line: usage.sourceLine,
    };
}
function toWorkflowListJsonItem(candidate) {
    return {
        templatePath: candidate.templatePath,
        system: candidate.system,
        source: candidate.source,
        targets: candidate.targets,
        autoSelect: candidate.autoSelect,
        updateMode: candidate.updateMode,
        requires: {
            skills: candidate.requiredSkills,
            mcp: candidate.requiredMcp,
        },
        description: candidate.description,
    };
}
async function runWorkflowLintCommand(cwd, args, locale) {
    const loadedConfig = await (0, control_plane_config_1.loadConfig)(cwd).catch(() => null);
    const workers = loadedConfig === null
        ? [...control_plane_config_1.DEFAULT_CONFIG.workers.default]
        : (0, control_plane_config_1.getConfiguredWorkerProviders)(loadedConfig);
    const maxNestedWorkflowDepth = loadedConfig?.maxNestedWorkflowDepth ??
        control_plane_config_1.DEFAULT_CONFIG.maxNestedWorkflowDepth;
    let catalog;
    try {
        catalog = await (0, template_registry_1.loadWorkflowTemplates)((0, template_registry_1.getWorkflowTemplatesDirectoryPath)(cwd), locale);
    }
    catch (error) {
        console.log(error instanceof Error
            ? error.message
            : (0, catalog_1.translate)(locale, "workflow.runContext.catalogLoadFailed"));
        return 1;
    }
    if (args.workflowTemplatePath) {
        const targetTemplatePath = (0, types_1.normalizeWorkflowTemplatePath)(args.workflowTemplatePath);
        if (targetTemplatePath === null) {
            console.log((0, catalog_1.translate)(locale, "workflow.command.lint.invalidPath", {
                value: args.workflowTemplatePath,
            }));
            return 1;
        }
        const template = catalog.templateByPath.get(targetTemplatePath);
        if (!template) {
            console.log(formatMissingWorkflowTemplateLintMessage({
                catalog,
                locale,
                targetTemplatePath,
            }));
            return 1;
        }
        const diagnostics = (0, validation_1.validateWorkflowTemplateRecord)({
            catalog,
            rootTemplate: template,
            maxNestedWorkflowDepth,
        }).diagnostics;
        const requiredSkillReport = await (0, required_skills_1.checkRequiredSkillAvailability)({
            repoRoot: cwd,
            workers,
            skillRefs: (0, required_skills_1.collectRequiredSkillsForWorkflowTree)({
                catalog,
                rootTemplate: template,
                maxNestedWorkflowDepth,
            }),
        });
        const requiredMcpReport = await (0, required_mcp_1.checkRequiredMcpAvailability)({
            repoRoot: cwd,
            workers,
            mcpRefs: (0, required_mcp_1.collectRequiredMcpForWorkflowTree)({
                catalog,
                rootTemplate: template,
                maxNestedWorkflowDepth,
            }),
        });
        const capabilityIntersectionReport = (0, required_capability_intersection_1.checkRequiredCapabilityWorkerIntersection)({
            skillReport: requiredSkillReport,
            mcpReport: requiredMcpReport,
        });
        console.log([
            (0, validation_1.formatWorkflowTemplateValidationReport)({
                locale,
                diagnostics,
                templatePath: template.templatePath,
            }),
            ...formatRequirementFailures(requiredSkillReport, requiredMcpReport, capabilityIntersectionReport, locale),
        ].join("\n"));
        return diagnostics.length === 0 &&
            requiredSkillReport.ok &&
            requiredMcpReport.ok &&
            capabilityIntersectionReport.ok
            ? 0
            : 1;
    }
    const diagnostics = (0, validation_1.validateWorkflowTemplateCatalog)({
        catalog,
        maxNestedWorkflowDepth,
    });
    const requiredSkillReport = await (0, required_skills_1.checkRequiredSkillAvailability)({
        repoRoot: cwd,
        workers,
        skillRefs: catalog.templates.flatMap((template) => template.metadata?.requiredSkills ?? []),
    });
    const requiredMcpReport = await (0, required_mcp_1.checkRequiredMcpAvailability)({
        repoRoot: cwd,
        workers,
        mcpRefs: catalog.templates.flatMap((template) => template.metadata?.requiredMcp ?? []),
    });
    const capabilityIntersectionReport = (0, required_capability_intersection_1.checkRequiredCapabilityWorkerIntersection)({
        skillReport: requiredSkillReport,
        mcpReport: requiredMcpReport,
    });
    console.log([
        (0, validation_1.formatWorkflowTemplateValidationReport)({
            locale,
            diagnostics,
        }),
        ...formatRequirementWarnings(requiredSkillReport, requiredMcpReport, capabilityIntersectionReport, locale),
    ].join("\n"));
    return diagnostics.length === 0 ? 0 : 1;
}
function formatMissingWorkflowTemplateLintMessage(input) {
    const lines = [
        (0, catalog_1.translate)(input.locale, "workflow.runContext.missingTemplate", {
            templatePath: input.targetTemplatePath,
        }),
        (0, catalog_1.translate)(input.locale, "workflow.runContext.available", {
            value: input.catalog.templates.length === 0
                ? (0, catalog_1.translate)(input.locale, "workflow.runContext.none")
                : input.catalog.templates
                    .map((templateEntry) => templateEntry.templatePath)
                    .map((templatePath) => `\`${templatePath}\``)
                    .join(", "),
        }),
    ];
    const suggestions = (0, template_registry_1.suggestWorkflowTemplatePaths)(input.catalog, input.targetTemplatePath);
    if (suggestions.length > 0) {
        lines.push((0, catalog_1.translate)(input.locale, "workflow.runContext.didYouMean", {
            value: suggestions
                .map((templatePath) => `\`${templatePath}\``)
                .join(", "),
        }));
    }
    return lines.join("\n");
}
function formatRequirementFailures(skillReport, mcpReport, capabilityIntersectionReport, locale) {
    return (0, required_capability_reports_1.formatRequiredCapabilityMessages)({
        requiredSkillReport: skillReport,
        requiredMcpReport: mcpReport,
        capabilityIntersectionReport,
        locale,
    });
}
function formatRequirementWarnings(skillReport, mcpReport, capabilityIntersectionReport, locale) {
    const messages = (0, required_capability_reports_1.formatRequiredCapabilityMessages)({
        requiredSkillReport: skillReport,
        requiredMcpReport: mcpReport,
        capabilityIntersectionReport,
        locale,
    });
    return messages.length === 0
        ? []
        : [
            (0, catalog_1.translate)(locale, "workflow.command.lint.requirementsWarning"),
            ...messages,
        ];
}
function formatWorkflowTemplateCandidates(candidates, locale, options = {}) {
    if (candidates.length === 0) {
        if ((options.hiddenSystemCandidateCount ?? 0) > 0) {
            return (0, catalog_1.translate)(locale, "workflow.command.list.noneNonSystem");
        }
        return (0, catalog_1.translate)(locale, "workflow.command.list.none");
    }
    return [
        "path\tsystem\tsource\ttargets\tautoSelect\tupdateMode\trequires.skills\trequires.mcp\tdescription",
        ...candidates.map((candidate) => [
            candidate.templatePath,
            candidate.system ? "yes" : "no",
            candidate.source,
            candidate.targets.join(","),
            candidate.autoSelect ? "yes" : "no",
            candidate.updateMode,
            candidate.requiredSkills.join(","),
            candidate.requiredMcp.join(","),
            candidate.description ?? "",
        ].join("\t")),
    ].join("\n");
}
function formatWorkflowTemplateReferenceUsages(usages, locale, targetPath) {
    if (usages.length === 0) {
        return (0, catalog_1.translate)(locale, "workflow.command.list.references.none", {
            templatePath: targetPath,
        });
    }
    return (0, template_reference_usages_1.formatWorkflowTemplateReferenceUsageTable)(usages);
}
