"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMilestoneWorkspace = createMilestoneWorkspace;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../../errors");
const command_write_summary_1 = require("../../license/command-write-summary");
const paths_1 = require("../../paths");
const authoring_policy_1 = require("../authoring-policy");
const front_matter_utils_1 = require("../front-matter-utils");
const governed_hierarchy_context_1 = require("../governed-hierarchy-context");
const legacy_milestone_scaffold_render_1 = require("../legacy-milestone-scaffold-render");
const milestone_scaffold_recovery_1 = require("../milestone-scaffold-recovery");
const runtime_acceptance_1 = require("../runtime-acceptance");
const scaffold_application_1 = require("../scaffold-application");
const upstream_specs_1 = require("../upstream-specs");
const scaffold_target_path_policy_1 = require("../scaffold-target-path-policy");
const authored_scaffold_1 = require("./authored-scaffold");
const overview_rendering_1 = require("./overview-rendering");
const phase_parsing_1 = require("./phase-parsing");
const projection_1 = require("./projection");
const support_rendering_1 = require("./support-rendering");
function createMilestoneWorkspace(repositoryRoot, options) {
    const runtimeEvidencePathPolicy = (0, scaffold_target_path_policy_1.readPlanningScaffoldTargetPathPolicy)(repositoryRoot);
    const phaseOverviewPath = (0, phase_parsing_1.resolvePhaseOverviewPath)(repositoryRoot, options.phaseOverviewPath);
    if (!node_fs_1.default.existsSync(phaseOverviewPath.absolute)) {
        throw (0, errors_1.createUsageError)(`Parent phase overview not found at '${phaseOverviewPath.relative}'.`, ["Run day-shift phase new first or pass the correct --phase-overview path."]);
    }
    const phaseOverviewText = node_fs_1.default.readFileSync(phaseOverviewPath.absolute, "utf8");
    const parentExpectedRevision = (0, scaffold_application_1.planningScaffoldContentRevision)(phaseOverviewText);
    const parsedPhaseOverview = (0, phase_parsing_1.parsePhaseOverview)(phaseOverviewPath.absolute, phaseOverviewText);
    (0, governed_hierarchy_context_1.assertCanonicalGovernedParentSync)(repositoryRoot, {
        layer: "phase",
        parentPath: phaseOverviewPath.relative,
        slice: parsedPhaseOverview.slice,
        phase: parsedPhaseOverview.phase,
        policy: parsedPhaseOverview.governedPolicy
    });
    const declaredMilestoneSlugs = (0, authoring_policy_1.declaredPlanningChildSlugs)(phaseOverviewText, "Milestones");
    const decompositionIssues = (0, authoring_policy_1.auditParentDecomposition)({
        artifactPath: phaseOverviewPath.relative,
        markdownText: phaseOverviewText,
        childKind: "milestone",
        declaredChildSlugs: declaredMilestoneSlugs
    });
    if (decompositionIssues.length > 0) {
        throw (0, errors_1.createUsageError)(`Planning decomposition contract rejected '${phaseOverviewPath.relative}' before milestone writes.`, (0, authoring_policy_1.formatParentDecompositionIssues)(decompositionIssues));
    }
    const upstreamSpecs = (0, upstream_specs_1.normalizeUpstreamSpecsToLocalSpecPaths)(repositoryRoot, parsedPhaseOverview.upstreamSpecs);
    const milestoneSlug = (0, phase_parsing_1.resolveMilestoneSlug)(options.milestoneSlug);
    if (!declaredMilestoneSlugs.includes(milestoneSlug)) {
        throw (0, errors_1.createUsageError)(`Milestone '${milestoneSlug}' is not declared by '${phaseOverviewPath.relative}'.`, ["Declare the milestone and update the authored target count and decomposition rationale before scaffolding."]);
    }
    const milestoneTitle = (0, phase_parsing_1.resolveMilestoneTitle)(milestoneSlug, options.milestoneTitle);
    if (options.recoverScaffold === true
        && options.milestoneTitle !== undefined
        && options.milestoneTitle.trim() !== "") {
        throw (0, errors_1.createUsageError)("--milestone-title cannot be combined with --recover-scaffold.", [
            "Recovery preserves the canonical generated milestone identity and replaces only a byte-exact untouched scaffold.",
            "No milestone artifact write was attempted."
        ]);
    }
    const milestoneDescription = (0, phase_parsing_1.resolveMilestoneDescription)(milestoneSlug, options.milestoneDescription, parsedPhaseOverview.milestoneDescriptions);
    const phaseDirectoryPath = node_path_1.default.dirname(phaseOverviewPath.absolute);
    const milestonesDirectoryPath = node_path_1.default.join(phaseDirectoryPath, "milestones");
    const milestoneDirectoryPath = node_path_1.default.join(milestonesDirectoryPath, milestoneSlug);
    const milestoneDirectoryRelative = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, milestoneDirectoryPath));
    const overviewRelativePath = (0, paths_1.composeCanonicalPlanningOverviewPath)("milestone", milestoneDirectoryRelative);
    const overviewPath = node_path_1.default.join(repositoryRoot, overviewRelativePath);
    const reconciliationPath = node_path_1.default.join(milestoneDirectoryPath, "reconciliation.md");
    const reconciliationRelativePath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, reconciliationPath));
    const authoredScaffoldEvidence = (0, authoring_policy_1.inspectChildScaffoldEvidence)({
        markdownText: phaseOverviewText,
        childKind: "milestone",
        childSlug: milestoneSlug,
        declaredChildSlugs: declaredMilestoneSlugs,
        runtimeEvidencePathPolicy
    });
    const scaffoldEvidence = authoredScaffoldEvidence;
    (0, overview_rendering_1.assertExecutableScaffoldEvidence)(phaseOverviewPath.relative, scaffoldEvidence);
    const authoredMilestoneScaffold = (0, authored_scaffold_1.inspectAuthoredMilestoneScaffold)({
        parentPath: phaseOverviewPath.relative,
        phaseMarkdownText: phaseOverviewText,
        milestoneSlug,
        declaredMilestoneSlugs,
        milestoneDescription,
        phaseAcceptanceCriteria: parsedPhaseOverview.acceptanceCriteria,
        authoritativeCriterionIds: parsedPhaseOverview.runtimeAcceptance?.required === true
            ? parsedPhaseOverview.runtimeAcceptance.criterionIds
            : [],
        scaffoldEvidence,
        runtimeEvidencePathPolicy
    });
    const taskCandidateSlugs = authoredMilestoneScaffold.tasks.map((task) => task.slug);
    const runtimeAcceptance = parsedPhaseOverview.runtimeAcceptance === null
        ? null
        : {
            ...(0, runtime_acceptance_1.childRuntimeAcceptanceMetadata)(parsedPhaseOverview.runtimeAcceptance, {
                breakoutTask: parsedPhaseOverview.runtimeAcceptance.required ? taskCandidateSlugs[0] : null
            }),
            criterionIds: parsedPhaseOverview.runtimeAcceptance.required
                ? [...authoredMilestoneScaffold.criterionIds]
                : []
        };
    const legacyTaskCandidateSlugs = (0, legacy_milestone_scaffold_render_1.legacyMilestoneTaskCandidateSlugs)(milestoneSlug);
    const legacyRuntimeAcceptance = parsedPhaseOverview.runtimeAcceptance === null
        ? null
        : (0, runtime_acceptance_1.childRuntimeAcceptanceMetadata)(parsedPhaseOverview.runtimeAcceptance, {
            breakoutTask: parsedPhaseOverview.runtimeAcceptance.required
                ? legacyTaskCandidateSlugs[0]
                : null
        });
    if (node_fs_1.default.existsSync(overviewPath)
        && parsedPhaseOverview.runtimeAcceptance !== null
        && options.recoverScaffold !== true) {
        const existingText = node_fs_1.default.readFileSync(overviewPath, "utf8");
        const existingFrontMatter = (0, phase_parsing_1.extractFrontMatter)(overviewPath, existingText);
        const existingInspection = (0, runtime_acceptance_1.inspectRuntimeAcceptance)({
            artifactPath: overviewPath,
            artifactKind: "milestone",
            frontMatterLines: existingFrontMatter.lines,
            markdownText: existingText,
            requireExplicitForExecutableEvidence: true
        });
        const inheritanceIssues = [
            ...existingInspection.issues,
            ...(0, runtime_acceptance_1.validateInheritedRuntimeAcceptance)(runtimeAcceptance ?? parsedPhaseOverview.runtimeAcceptance, existingInspection.metadata)
        ];
        if (inheritanceIssues.length > 0) {
            throw (0, errors_1.createUsageError)(`Runtime acceptance contract rejected '${(0, front_matter_utils_1.toRepositoryLikePath)(overviewPath)}'.`, inheritanceIssues);
        }
    }
    const overviewExistsBeforeWrite = node_fs_1.default.existsSync(overviewPath);
    const reconciliationExistsBeforeWrite = node_fs_1.default.existsSync(reconciliationPath);
    if (overviewExistsBeforeWrite) {
        (0, governed_hierarchy_context_1.assertExistingGovernedArtifactSync)(overviewPath, {
            artifactType: "milestone_overview",
            slice: parsedPhaseOverview.slice,
            phase: parsedPhaseOverview.phase,
            milestone: milestoneSlug,
            planningDepth: parsedPhaseOverview.planningDepth,
            upstream: {
                slice_overview: parsedPhaseOverview.sliceOverviewPath,
                phase_overview: phaseOverviewPath.relative
            }
        });
    }
    if (reconciliationExistsBeforeWrite) {
        (0, governed_hierarchy_context_1.assertExistingGovernedArtifactSync)(reconciliationPath, {
            artifactType: "reconciliation",
            slice: parsedPhaseOverview.slice,
            phase: parsedPhaseOverview.phase,
            milestone: milestoneSlug,
            planningDepth: parsedPhaseOverview.planningDepth,
            upstream: {
                slice_overview: parsedPhaseOverview.sliceOverviewPath,
                phase_overview: phaseOverviewPath.relative,
                milestone_overview: overviewRelativePath
            }
        });
    }
    const recoveryWorkflowCliCommand = options.recoverScaffold === true
        && overviewExistsBeforeWrite
        ? (0, phase_parsing_1.readTopLevelField)((0, phase_parsing_1.extractFrontMatter)(overviewPath, node_fs_1.default.readFileSync(overviewPath, "utf8")).lines, "workflow_cli_command")
        : undefined;
    const artifactWorkflowCliCommand = recoveryWorkflowCliCommand ?? options.workflowCliCommand;
    const expectedRenderedOverview = (0, authoring_policy_1.stampPlanningScaffoldProjectionRevision)((0, overview_rendering_1.renderMilestoneOverviewMarkdown)({
        milestoneTitle,
        slice: parsedPhaseOverview.slice,
        phase: parsedPhaseOverview.phase,
        milestoneSlug,
        milestoneDescription,
        planningDepth: parsedPhaseOverview.planningDepth,
        sliceOverviewPath: parsedPhaseOverview.sliceOverviewPath,
        phaseOverviewPath: phaseOverviewPath.relative,
        upstreamSpecs,
        governedPolicy: parsedPhaseOverview.governedPolicy,
        phasePurpose: parsedPhaseOverview.purpose,
        milestoneAcceptanceCriteria: authoredMilestoneScaffold.acceptanceCriteria,
        phaseRisks: parsedPhaseOverview.risks,
        scaffoldEvidence,
        authoredMilestoneScaffold,
        runtimeAcceptance,
        workflowCliCommand: artifactWorkflowCliCommand
    }), "milestone");
    const scaffoldProjection = overviewExistsBeforeWrite
        ? (0, authoring_policy_1.comparePlanningScaffoldProjections)((0, authoring_policy_1.projectPlanningScaffoldContract)(expectedRenderedOverview, "milestone"), (0, authoring_policy_1.projectPlanningScaffoldContract)(node_fs_1.default.readFileSync(overviewPath, "utf8"), "milestone"))
        : null;
    const recordedProjectionRevision = overviewExistsBeforeWrite
        ? (0, authoring_policy_1.readPlanningScaffoldProjectionRevision)(node_fs_1.default.readFileSync(overviewPath, "utf8"))
        : null;
    const legacyRecoveryCandidate = options.recoverScaffold === true
        && recordedProjectionRevision === null;
    const projectionRefresh = scaffoldProjection !== null
        && !scaffoldProjection.current
        && options.recoverScaffold === true
        && !legacyRecoveryCandidate;
    if (scaffoldProjection !== null
        && !scaffoldProjection.current
        && !legacyRecoveryCandidate) {
        (0, projection_1.assertMilestoneProjectionRefreshAllowed)({
            overviewPath,
            artifactPath: overviewRelativePath,
            reconciliationPath,
            tasksDirectoryPath: node_path_1.default.join(milestoneDirectoryPath, "tasks"),
            observedText: node_fs_1.default.readFileSync(overviewPath, "utf8"),
            comparison: scaffoldProjection,
            refreshRequested: options.recoverScaffold === true
        });
    }
    const renderedOverview = !overviewExistsBeforeWrite || options.recoverScaffold === true
        ? expectedRenderedOverview
        : null;
    const renderedReconciliation = !reconciliationExistsBeforeWrite || options.recoverScaffold === true
        ? (0, support_rendering_1.renderMilestoneReconciliationMarkdown)({
            repositoryRoot,
            milestoneTitle,
            slice: parsedPhaseOverview.slice,
            phase: parsedPhaseOverview.phase,
            milestoneSlug,
            planningDepth: parsedPhaseOverview.planningDepth,
            sliceOverviewPath: parsedPhaseOverview.sliceOverviewPath,
            phaseOverviewPath: phaseOverviewPath.relative,
            milestoneOverviewPath: overviewRelativePath,
            upstreamSpecs,
            workflowCliCommand: artifactWorkflowCliCommand
        })
        : null;
    const overviewExists = node_fs_1.default.existsSync(overviewPath);
    const reconciliationExists = node_fs_1.default.existsSync(reconciliationPath);
    const recoveryInspection = options.recoverScaffold === true && !projectionRefresh
        ? (0, milestone_scaffold_recovery_1.inspectMilestoneScaffoldRecoveryPairSync)({
            overviewPath,
            reconciliationPath,
            tasksDirectoryPath: node_path_1.default.join(milestoneDirectoryPath, "tasks"),
            expectedLegacyOverviewText: (0, legacy_milestone_scaffold_render_1.renderLegacyMilestoneOverviewMarkdown)({
                milestoneTitle,
                milestoneDescription,
                slice: parsedPhaseOverview.slice,
                phase: parsedPhaseOverview.phase,
                milestoneSlug,
                planningDepth: parsedPhaseOverview.planningDepth,
                sliceOverviewPath: parsedPhaseOverview.sliceOverviewPath,
                phaseOverviewPath: phaseOverviewPath.relative,
                overviewRelativePath,
                reconciliationRelativePath,
                upstreamSpecs,
                governedPolicy: parsedPhaseOverview.governedPolicy,
                phasePurpose: parsedPhaseOverview.purpose,
                phaseScope: parsedPhaseOverview.scope,
                phaseAcceptanceCriteria: parsedPhaseOverview.acceptanceCriteria,
                phaseDependencies: parsedPhaseOverview.dependencies,
                phaseRisks: parsedPhaseOverview.risks,
                phaseValidationFocus: parsedPhaseOverview.validationFocus,
                runtimeAcceptance: legacyRuntimeAcceptance,
                workflowCliCommand: artifactWorkflowCliCommand
            }),
            expectedLegacyReconciliationText: renderedReconciliation ?? "",
            expectedRecoveredOverviewText: renderedOverview ?? undefined,
            expectedRecoveredReconciliationText: renderedReconciliation ?? undefined
        })
        : null;
    if (recoveryInspection !== null && !recoveryInspection.eligible) {
        throw (0, errors_1.createUsageError)(`Milestone scaffold recovery rejected '${overviewRelativePath}' before writes.`, [...recoveryInspection.issues, "No milestone artifact write was attempted."]);
    }
    const milestonesDirectoryAction = node_fs_1.default.existsSync(milestonesDirectoryPath) ? "kept" : "created";
    const plannedWrites = [
        ...(projectionRefresh && renderedOverview !== null
            ? [{
                    path: overviewRelativePath,
                    contents: renderedOverview,
                    mode: "replace",
                    expectedRevision: (0, scaffold_application_1.planningScaffoldContentRevision)(node_fs_1.default.readFileSync(overviewPath))
                }]
            : recoveryInspection?.action === "replace"
                && renderedOverview !== null
                && recoveryInspection.overviewText !== renderedOverview
                && recoveryInspection.overviewExpectedRevision !== null
                ? [{
                        path: overviewRelativePath,
                        contents: renderedOverview,
                        mode: "replace",
                        expectedRevision: recoveryInspection.overviewExpectedRevision
                    }]
                : !overviewExists && renderedOverview !== null
                    ? [{ path: overviewRelativePath, contents: renderedOverview }]
                    : []),
        ...(recoveryInspection?.action === "replace"
            && renderedReconciliation !== null
            && recoveryInspection.reconciliationText !== renderedReconciliation
            && recoveryInspection.reconciliationExpectedRevision !== null
            ? [{
                    path: reconciliationRelativePath,
                    contents: renderedReconciliation,
                    mode: "replace",
                    expectedRevision: recoveryInspection.reconciliationExpectedRevision
                }]
            : !reconciliationExists && renderedReconciliation !== null
                ? [{
                        path: reconciliationRelativePath,
                        contents: renderedReconciliation
                    }]
                : [])
    ];
    const overviewRefreshed = plannedWrites.some((write) => write.path === overviewRelativePath && write.mode === "replace");
    const reconciliationRefreshed = plannedWrites.some((write) => write.path === reconciliationRelativePath && write.mode === "replace");
    let application = {
        outcome: "no-write",
        intendedPaths: [],
        changedPaths: [],
        transactionId: null,
        conflicts: [],
        recoveryPath: null,
        failure: null
    };
    if (options.validateOnly !== true) {
        application = (0, scaffold_application_1.applyPlanningScaffoldSync)(repositoryRoot, plannedWrites, {
            parentPaths: [{
                    path: phaseOverviewPath.relative,
                    expectedRevision: parentExpectedRevision
                }]
        });
        (0, scaffold_application_1.assertPlanningScaffoldApplied)(application);
    }
    return {
        repositoryRoot,
        slice: parsedPhaseOverview.slice,
        phase: parsedPhaseOverview.phase,
        planningDepth: parsedPhaseOverview.planningDepth,
        phaseOverviewPath: phaseOverviewPath.relative,
        milestonesDirectoryPath,
        milestoneDirectoryPath,
        overviewPath,
        reconciliationPath,
        milestoneSlug,
        milestoneTitle,
        parentExpectedRevision,
        milestonesDirectoryAction,
        overviewAction: overviewRefreshed
            ? "refreshed"
            : overviewExists
                ? "kept"
                : "created",
        reconciliationAction: reconciliationRefreshed
            ? "refreshed"
            : reconciliationExists
                ? "kept"
                : "created",
        contributingSpecIds: upstreamSpecs.map((entry) => entry.id),
        plannedWrites,
        requiresRefinement: false,
        scaffoldEvidence,
        scaffoldProjection,
        application,
        commandWriteSummary: (0, command_write_summary_1.normalizeCommandWriteSummary)({
            commandFamily: "milestone_generation",
            primaryOutputArtifacts: [overviewRelativePath, reconciliationRelativePath],
            updatedArtifacts: [
                {
                    path: overviewRelativePath,
                    action: overviewRefreshed
                        ? "refreshed"
                        : overviewExists
                            ? "kept"
                            : "created",
                    reason: overviewRefreshed
                        ? "accepted_refresh"
                        : overviewExists
                            ? "no_write"
                            : "accepted_create"
                },
                {
                    path: reconciliationRelativePath,
                    action: reconciliationRefreshed
                        ? "refreshed"
                        : reconciliationExists
                            ? "kept"
                            : "created",
                    reason: reconciliationRefreshed
                        ? "accepted_refresh"
                        : reconciliationExists
                            ? "no_write"
                            : "accepted_create"
                }
            ]
        })
    };
}
