"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TASK_ID_PATTERN = void 0;
exports.resolveGovernedSliceSourceEvidence = resolveGovernedSliceSourceEvidence;
exports.hasGovernedRoutingChanges = hasGovernedRoutingChanges;
exports.assertExistingGovernedRoutingEvidence = assertExistingGovernedRoutingEvidence;
exports.validateInitiativeId = validateInitiativeId;
exports.renderGovernedSliceOverview = renderGovernedSliceOverview;
exports.renderWorkOverview = renderWorkOverview;
exports.normalizeSpecificationPaths = normalizeSpecificationPaths;
exports.requireRepositoryRoot = requireRepositoryRoot;
exports.yamlString = yamlString;
exports.workflowLevelLabel = workflowLevelLabel;
exports.nextActionForOutcome = nextActionForOutcome;
exports.nextActionForGovernedOutcome = nextActionForGovernedOutcome;
exports.parseStructuredOverview = parseStructuredOverview;
exports.parseStructuredOverviewSpecifications = parseStructuredOverviewSpecifications;
exports.normalizeStructuredTaskInputs = normalizeStructuredTaskInputs;
exports.validateStructuredTaskGraph = validateStructuredTaskGraph;
// Structured and governed overview plus task-pair creation orchestration.
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const cli_constants_1 = require("../config/cli-constants");
const paths_1 = require("../paths");
const canonical_write_target_1 = require("../paths/canonical-write-target");
const ordered_root_identity_1 = require("../planning/ordered-root-identity");
const planning_document_utils_1 = require("../planning/planning-document-utils");
const spec_registry_1 = require("../spec-registry");
const creation_overview_1 = require("./creation-overview");
const task_rendering_1 = require("./task-rendering");
function resolveGovernedSliceSourceEvidence(repositoryRoot, specifications, requestedInitiativeId) {
    const indexTarget = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, cli_constants_1.CLI_SPEC_INDEX_PATH);
    if (!indexTarget.exists || !node_fs_1.default.statSync(indexTarget.runtimePath).isFile()) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Governed slice creation requires the canonical specification registry.");
    }
    let indexDocument;
    try {
        indexDocument = (0, spec_registry_1.parseSpecIndexDocumentText)(node_fs_1.default.readFileSync(indexTarget.runtimePath, "utf8"));
    }
    catch (error) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Governed slice creation could not parse specification registry evidence: ${error instanceof Error ? error.message : String(error)}`);
    }
    const selectedEntries = specifications.map((specification) => {
        const entry = indexDocument.entries.find((candidate) => candidate.id === specification.specId
            && candidate.spec_path === specification.specPath);
        if (entry === undefined) {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Specification '${specification.specId}' is missing matching canonical registry evidence.`);
        }
        return entry;
    });
    const planningDepths = new Set(selectedEntries.map((entry) => entry.depth ?? "standard"));
    if (planningDepths.size !== 1) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Governed source specifications resolve to conflicting planning depths: ${[...planningDepths].join(", ")}.`);
    }
    const initiativeCandidates = new Set(selectedEntries
        .map((entry) => entry.additionalMetadata.initiative_id)
        .filter((value) => typeof value === "string" && value.trim() !== "")
        .map((value) => validateInitiativeId(value.trim())));
    if (requestedInitiativeId !== undefined && requestedInitiativeId !== null) {
        initiativeCandidates.add(validateInitiativeId(requestedInitiativeId));
    }
    if (initiativeCandidates.size > 1) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Governed source specifications contain conflicting initiative identities: ${[
            ...initiativeCandidates
        ].join(", ")}.`);
    }
    return {
        initiativeId: initiativeCandidates.size === 0 ? null : [...initiativeCandidates][0],
        planningDepth: [...planningDepths][0],
        entries: selectedEntries,
        indexDocument,
        indexTarget
    };
}
function hasGovernedRoutingChanges(current, routed, contributors) {
    return contributors.some((entry) => {
        const next = routed.entries.find((candidate) => candidate.id === entry.id);
        const previous = current.entries.find((candidate) => candidate.id === entry.id);
        return next === undefined
            || previous === undefined
            || previous.depth !== next.depth
            || previous.destination !== next.destination
            || previous.optional.implementation_order !== next.optional.implementation_order
            || previous.optional.linked_slice?.slice !== next.optional.linked_slice?.slice
            || previous.optional.linked_slice?.path !== next.optional.linked_slice?.path;
    });
}
function assertExistingGovernedRoutingEvidence(entries) {
    for (const entry of entries) {
        const order = typeof entry.optional.implementation_order === "number"
            && Number.isFinite(entry.optional.implementation_order)
            ? String(entry.optional.implementation_order)
            : typeof entry.optional.implementation_order === "string"
                ? entry.optional.implementation_order.trim()
                : "";
        if (order === "") {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Specification '${entry.id}' has no explicit implementation_order evidence.`);
        }
        if (entry.optional.linked_slice === undefined && entry.destination === undefined) {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Specification '${entry.id}' does not resolve to a canonical slice slug.`);
        }
    }
}
function validateInitiativeId(value) {
    if (!(0, paths_1.isCanonicalSlug)(value)) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Governed initiative identity must be a lowercase kebab-case identifier.");
    }
    return value;
}
function renderGovernedSliceOverview(input) {
    const upstream = input.specifications.flatMap((specification) => [
        `    - id: ${yamlString(specification.specId)}`,
        `      depth: ${yamlString(input.planningDepth)}`,
        `      ref: ${yamlString(specification.specPath)}`,
        '      source_type: "markdown"',
        `      revision: ${yamlString(specification.revision)}`,
        `      readiness: ${yamlString(specification.readiness)}`
    ]);
    const sources = input.specifications.map((specification) => `- \`${specification.specId}\`: \`${specification.specPath}\` at revision \`${specification.revision}\` (${specification.readiness}).`);
    return [
        "---",
        "artifact_schema_version: 1",
        "artifact_type: slice_overview",
        `id: ${yamlString(input.sliceId)}`,
        `slice: ${yamlString(input.sliceId)}`,
        `implementation_order: ${yamlString(input.implementationOrder)}`,
        `planning_depth: ${yamlString(input.planningDepth)}`,
        "workflow_level: governed",
        `default_agent_mode: ${yamlString(input.defaultAgentMode)}`,
        `default_agent_mode_source: ${yamlString(input.defaultAgentModeSource)}`,
        `default_evidence_profile: ${yamlString(input.defaultEvidenceProfile)}`,
        `default_evidence_profile_source: ${yamlString(input.defaultEvidenceProfileSource)}`,
        ...(input.initiativeId === null
            ? []
            : [`initiative_id: ${yamlString(input.initiativeId)}`]),
        "status: draft",
        "upstream:",
        "  specs:",
        ...upstream,
        "---",
        "",
        `# ${input.sliceId}`,
        "",
        "## Purpose",
        "",
        `Establish the independently governed planning root for ${input.sliceSlug} from revision-bound canonical specification evidence.`,
        "",
        "## Source Specifications",
        "",
        ...sources,
        "",
        "## Desired Outcome",
        "",
        `A lifecycle-complete Governed hierarchy can be planned beneath \`.day-shift/planning/governed/${input.sliceId}/\` without a work-overview parent.`,
        "",
        "## Scope",
        "",
        "- Preserve one ordered Governed slice root and list-based source traceability.",
        "- Keep phase, milestone, task, implementation, reconciliation, and project-review evidence beneath this root.",
        "- Treat initiative identity, when present, as non-hierarchical grouping evidence.",
        "",
        "## Non-Goals",
        "",
        "- Create child planning artifacts during Governed root creation.",
        "- Migrate or normalize an existing Governed hierarchy.",
        "",
        "## Planning Depth",
        "",
        input.planningDepth,
        "",
        "## Planning Defaults",
        "",
        `- Default agent mode: \`${input.defaultAgentMode}\` (source: \`${input.defaultAgentModeSource}\`).`,
        `- Default evidence profile: \`${input.defaultEvidenceProfile}\` (source: \`${input.defaultEvidenceProfileSource}\`).`,
        "",
        "## Phases",
        "",
        "- To be planned.",
        "",
        "## Decisions",
        "",
        `- The canonical Governed identity is \`${input.sliceId}\`.`,
        "",
        "## Risks",
        "",
        "- Follow-on hierarchy edits must retain slice-owned identity and source revisions.",
        "",
        "## Validation Strategy",
        "",
        "- Validate metadata, parent links, and child lifecycle evidence with focused CLI checks.",
        "",
        "## Open Questions",
        "",
        "- None currently.",
        ""
    ].join("\n");
}
function renderWorkOverview(input) {
    const levelLabel = workflowLevelLabel(input.workflowLevel);
    const purpose = input.workflowLevel === "governed"
        ? "Establish the governed planning root for implementation work from the referenced canonical specifications without duplicating their authored requirements."
        : "Organize implementation work from the referenced canonical specifications without duplicating their authored requirements.";
    const planHeading = input.workflowLevel === "governed" ? "Hierarchy Plan" : "Task Plan";
    const planGuidance = input.workflowLevel === "governed"
        ? "The complete Governed hierarchy is created through a separate explicit hierarchy-planning action."
        : [
            "Direct task pairs are created through a separate explicit Structured task-planning action.",
            "Declare each task with its ordered directory name, unprefixed semantic task ID, and parent-local sequence.",
            "> - `01-example-task` (`task_id`: `example-task`; sequence: 1): Describe the task outcome.",
            "The `task_id` stays unprefixed; `work task create` applies the sequence prefix and creates `tasks/01-example-task/`."
        ].join("\n\n");
    const reviewGuidance = input.workflowLevel === "governed"
        ? "Formal reconciliation and project review are created only by separately authorized Governed lifecycle actions."
        : "Project review is created only by a separately authorized review-persistence action.";
    const upstream = input.specifications.flatMap((specification) => [
        `    - id: ${yamlString(specification.specId)}`,
        `      ref: ${yamlString(specification.specPath)}`,
        `      revision: ${yamlString(specification.revision)}`,
        `      readiness: ${yamlString(specification.readiness)}`
    ]);
    const sources = input.specifications.map((specification) => `- \`${specification.specId}\`: \`${specification.specPath}\` at revision \`${specification.revision}\` (${specification.readiness}).`);
    return [
        "---",
        "artifact_schema_version: 1",
        "artifact_type: work_overview",
        `id: ${yamlString(input.workId)}`,
        `implementation_order: ${yamlString(input.implementationOrder)}`,
        `workflow_level: ${input.workflowLevel}`,
        `default_agent_mode: ${yamlString(input.defaultAgentMode)}`,
        `default_agent_mode_source: ${yamlString(input.defaultAgentModeSource)}`,
        `default_evidence_profile: ${yamlString(input.defaultEvidenceProfile)}`,
        `default_evidence_profile_source: ${yamlString(input.defaultEvidenceProfileSource)}`,
        "status: draft",
        "upstream:",
        "  specs:",
        ...upstream,
        "---",
        "",
        `# ${levelLabel} Work: ${input.workId}`,
        "",
        "## Purpose",
        "",
        purpose,
        "",
        "## Source Specifications",
        "",
        ...sources,
        "",
        "## Planning Defaults",
        "",
        `- Default agent mode: \`${input.defaultAgentMode}\` (source: \`${input.defaultAgentModeSource}\`).`,
        `- Default evidence profile: \`${input.defaultEvidenceProfile}\` (source: \`${input.defaultEvidenceProfileSource}\`).`,
        "",
        `## ${planHeading}`,
        "",
        planGuidance,
        "",
        "## Review Requirements",
        "",
        reviewGuidance,
        "",
        "## Open Questions",
        "",
        "- None currently.",
        ""
    ].join("\n");
}
function normalizeSpecificationPaths(input) {
    if (!Array.isArray(input)) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Specification paths must be a list.");
    }
    return input.map((value) => {
        if (typeof value !== "string" || value.trim() === "") {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Specification paths must be non-empty repository-relative strings.");
        }
        return value.trim();
    });
}
function requireRepositoryRoot(input) {
    if (typeof input !== "string" || input.trim() === "") {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Repository root is required.");
    }
    return node_path_1.default.resolve(input);
}
function yamlString(value) {
    return JSON.stringify(value);
}
function workflowLevelLabel(level) {
    return level === "governed" ? "Governed" : "Structured";
}
function nextActionForOutcome(outcome, workflowLevel) {
    if (outcome === "committed") {
        return workflowLevel === "governed"
            ? "Create the complete Governed hierarchy through a separate explicit action."
            : "Create direct Structured task pairs through a separate explicit action.";
    }
    if (outcome === "conflict") {
        return `Refresh the ${workflowLevelLabel(workflowLevel)} work creation preview and review changed evidence.`;
    }
    if (outcome === "incomplete")
        return "Inspect retained transaction evidence before retrying or recovering.";
    return `Refresh the ${workflowLevelLabel(workflowLevel)} work creation preview; no canonical write was required.`;
}
function nextActionForGovernedOutcome(outcome) {
    if (outcome === "conflict") {
        return "Refresh the Governed slice creation preview and review changed evidence.";
    }
    if (outcome === "incomplete") {
        return "Inspect retained transaction evidence before retrying or recovering.";
    }
    return "Refresh the Governed slice creation preview; no canonical write was required.";
}
function parseStructuredOverview(markdownText, overviewPath) {
    const document = (0, planning_document_utils_1.parseMarkdownFrontMatter)(markdownText);
    if (!document.hasFrontMatter) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Structured overview is missing YAML front matter.");
    }
    const artifactType = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "artifact_type");
    const workflowLevel = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "workflow_level");
    const workId = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "id");
    if (artifactType !== "work_overview" || workflowLevel !== "structured" || workId === undefined) {
        throw new creation_overview_1.StructuredWorkCreationError("unsupported-level", `Overview '${overviewPath}' must be a canonical Structured work_overview with a stable id.`);
    }
    let directoryIdentity;
    try {
        directoryIdentity = (0, ordered_root_identity_1.parseOrderedDirectoryIdentity)("structured-root", node_path_1.default.posix.basename(node_path_1.default.posix.dirname(overviewPath)));
    }
    catch (error) {
        throw (0, task_rendering_1.normalizeOrderedRootCreationError)(error);
    }
    if (!exports.TASK_ID_PATTERN.test(workId) || directoryIdentity.stableId !== workId) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured overview identity '${workId}' does not match its canonical directory.`);
    }
    const recordedImplementationOrder = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "implementation_order");
    let implementationOrder = directoryIdentity.orderPrefix;
    if (recordedImplementationOrder !== undefined) {
        try {
            implementationOrder = (0, ordered_root_identity_1.normalizeImplementationOrder)(recordedImplementationOrder);
        }
        catch (error) {
            throw (0, task_rendering_1.normalizeOrderedRootCreationError)(error);
        }
    }
    if (directoryIdentity.shape === "canonical" && recordedImplementationOrder === undefined) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured overview '${overviewPath}' is numbered but lacks implementation_order metadata.`);
    }
    if (directoryIdentity.orderPrefix !== null
        && implementationOrder !== directoryIdentity.orderPrefix) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured overview '${overviewPath}' directory prefix disagrees with implementation_order.`);
    }
    const specifications = parseStructuredOverviewSpecifications(document.frontMatterLines);
    if (specifications.length === 0) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Structured overview must retain at least one revision-bound source specification.");
    }
    return {
        workId,
        implementationOrder,
        defaultAgentMode: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "default_agent_mode") ?? null,
        defaultEvidenceProfile: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "default_evidence_profile") ?? null,
        specifications
    };
}
function parseStructuredOverviewSpecifications(lines) {
    const specifications = [];
    let inUpstream = false;
    let inSpecs = false;
    let current = null;
    const finish = () => {
        if (current === null)
            return;
        if (current.specId === undefined || current.specPath === undefined || current.revision === undefined) {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "Structured overview contains incomplete source specification evidence.");
        }
        specifications.push({
            specId: current.specId,
            specPath: (0, task_rendering_1.requireRepositoryRelativeInput)(current.specPath, "Specification path"),
            revision: current.revision,
            readiness: current.readiness ?? null
        });
        current = null;
    };
    for (const line of lines) {
        if (line === "upstream:") {
            inUpstream = true;
            continue;
        }
        if (!inUpstream)
            continue;
        if (/^[^\s]/.test(line))
            break;
        if (line === "  specs:") {
            inSpecs = true;
            continue;
        }
        if (!inSpecs)
            continue;
        const idMatch = line.match(/^\s{4}-\s+id:\s*(.*)$/);
        if (idMatch !== null) {
            finish();
            current = { specId: (0, planning_document_utils_1.parseScalar)(idMatch[1]) };
            continue;
        }
        const fieldMatch = line.match(/^\s{6}(ref|revision|readiness):\s*(.*)$/);
        if (fieldMatch !== null && current !== null) {
            const value = (0, planning_document_utils_1.parseScalar)(fieldMatch[2]);
            if (fieldMatch[1] === "ref")
                current.specPath = value;
            if (fieldMatch[1] === "revision")
                current.revision = value;
            if (fieldMatch[1] === "readiness")
                current.readiness = value;
        }
    }
    finish();
    return specifications;
}
exports.TASK_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
function normalizeStructuredTaskInputs(tasks) {
    if (!Array.isArray(tasks) || tasks.length === 0) {
        throw new creation_overview_1.StructuredWorkCreationError("invalid-request", "At least one Structured task is required.");
    }
    return tasks.map((task, index) => {
        if (task === null || typeof task !== "object") {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task ${index + 1} must be an object.`);
        }
        const taskId = (0, task_rendering_1.requireText)(task.taskId, `Structured task ${index + 1} id`);
        if (!exports.TASK_ID_PATTERN.test(taskId)) {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task id '${taskId}' must be lowercase kebab-case.`);
        }
        return {
            ...task,
            taskId,
            title: (0, task_rendering_1.optionalText)(task.title) ?? (0, task_rendering_1.titleFromSlug)(taskId),
            objective: (0, task_rendering_1.requireText)(task.objective, `Structured task '${taskId}' objective`),
            targetPaths: (0, task_rendering_1.requireStringList)(task.targetPaths, `Structured task '${taskId}' targetPaths`, true)
                .map((value) => (0, task_rendering_1.requireRepositoryRelativeInput)(value, "Task target path")),
            currentBehavior: (0, task_rendering_1.optionalText)(task.currentBehavior) ?? "The requested task outcome is not implemented yet.",
            desiredBehavior: (0, task_rendering_1.requireText)(task.desiredBehavior, `Structured task '${taskId}' desiredBehavior`),
            acceptanceCriteria: (0, task_rendering_1.requireStringList)(task.acceptanceCriteria, `Structured task '${taskId}' acceptanceCriteria`, true),
            validationCommands: (0, task_rendering_1.requireStringList)(task.validationCommands, `Structured task '${taskId}' validationCommands`, true),
            rollbackRecovery: (0, task_rendering_1.requireText)(task.rollbackRecovery, `Structured task '${taskId}' rollbackRecovery`),
            dependencies: (0, task_rendering_1.requireStringList)(task.dependencies ?? [], `Structured task '${taskId}' dependencies`, false),
            constraints: (0, task_rendering_1.requireStringList)(task.constraints ?? [], `Structured task '${taskId}' constraints`, false)
        };
    });
}
function validateStructuredTaskGraph(tasks, existingTaskIds = []) {
    const positions = new Map();
    const existing = new Set(existingTaskIds);
    for (const [index, task] of tasks.entries()) {
        if (positions.has(task.taskId) || existing.has(task.taskId)) {
            throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task id '${task.taskId}' is supplied more than once or already active.`);
        }
        positions.set(task.taskId, index);
    }
    for (const [index, task] of tasks.entries()) {
        const observed = new Set();
        for (const dependency of task.dependencies) {
            if (!exports.TASK_ID_PATTERN.test(dependency)) {
                throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task '${task.taskId}' dependency '${dependency}' is not a valid task id.`);
            }
            if (observed.has(dependency)) {
                throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task '${task.taskId}' repeats dependency '${dependency}'.`);
            }
            observed.add(dependency);
            const dependencyPosition = positions.get(dependency);
            if (dependencyPosition === undefined && !existing.has(dependency)) {
                throw new creation_overview_1.StructuredWorkCreationError("invalid-request", `Structured task '${task.taskId}' dependency '${dependency}' is not active or in this creation request.`);
            }
            if (dependencyPosition !== undefined && dependencyPosition >= index) {
                throw new creation_overview_1.StructuredWorkCreationError("invalid-request", dependency === task.taskId
                    ? `Structured task '${task.taskId}' cannot depend on itself.`
                    : `Structured task '${task.taskId}' cannot depend on later task '${dependency}'.`);
            }
        }
    }
}
