"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.taskPairPlans = exports.plans = exports.StructuredWorkCreationError = void 0;
exports.previewStructuredWorkCreationSync = previewStructuredWorkCreationSync;
exports.previewGovernedWorkCreationSync = previewGovernedWorkCreationSync;
exports.previewWorkOverviewCreationSync = previewWorkOverviewCreationSync;
exports.applyStructuredWorkCreationSync = applyStructuredWorkCreationSync;
exports.applyGovernedWorkCreationSync = applyGovernedWorkCreationSync;
exports.applyWorkOverviewCreationSync = applyWorkOverviewCreationSync;
// 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 mutation_preconditions_1 = require("../filesystem/mutation-preconditions");
const repository_transaction_1 = require("../filesystem/repository-transaction");
const canonical_write_target_1 = require("../paths/canonical-write-target");
const ordered_root_identity_1 = require("../planning/ordered-root-identity");
const policy_resolution_1 = require("../planning/policy-resolution");
const slice_generation_1 = require("../planning/slice-generation");
const spec_registry_1 = require("../spec-registry");
const work_routing_1 = require("../work-routing");
const governed_overview_1 = require("./governed-overview");
const task_pair_creation_1 = require("./task-pair-creation");
const task_rendering_1 = require("./task-rendering");
class StructuredWorkCreationError extends Error {
    code;
    constructor(code, message) {
        super(message);
        this.name = "StructuredWorkCreationError";
        this.code = code;
    }
}
exports.StructuredWorkCreationError = StructuredWorkCreationError;
exports.plans = new WeakMap();
exports.taskPairPlans = new WeakMap();
function previewStructuredWorkCreationSync(request) {
    return previewWorkOverviewCreationSync(request, "structured");
}
function previewGovernedWorkCreationSync(request) {
    if (request.workId !== undefined) {
        throw new StructuredWorkCreationError("invalid-request", "Governed creation accepts slice identity only; workId is not applicable.");
    }
    const repositoryRoot = (0, governed_overview_1.requireRepositoryRoot)(request.repositoryRoot);
    const specificationPaths = (0, governed_overview_1.normalizeSpecificationPaths)(request.specificationPaths);
    const level = (0, work_routing_1.resolveWorkflowLevel)({
        explicit: request.level ?? "governed",
        parent: request.parentLevel,
        project: request.projectLevel,
        repository: request.repositoryLevel,
        user: request.userLevel,
        recommendation: request.recommendation,
        recommendationAccepted: request.recommendationAccepted,
        specificationCount: specificationPaths.length,
        interactive: false
    });
    if (level.level !== "governed") {
        throw new StructuredWorkCreationError("unsupported-level", `Governed slice creation cannot create '${level.level}' work. Use the level-specific producer.`);
    }
    const specifications = [...(0, work_routing_1.normalizeSpecificationReferencesSync)(repositoryRoot, {
            level: "governed",
            specificationPaths
        })].sort((left, right) => left.specId.localeCompare(right.specId));
    const sourceEvidence = (0, governed_overview_1.resolveGovernedSliceSourceEvidence)(repositoryRoot, specifications, request.initiativeId);
    const registryRoutingAuthorized = request.authorizeRegistryRouting === true;
    if (!registryRoutingAuthorized) {
        (0, governed_overview_1.assertExistingGovernedRoutingEvidence)(sourceEvidence.entries);
    }
    const planningRoot = request.planningRoot ?? ".day-shift/planning";
    const identity = (0, slice_generation_1.allocateGovernedSliceDestination)({
        entries: sourceEvidence.indexDocument.entries,
        selectedSpecIds: specifications.map((specification) => specification.specId),
        requestedSliceId: request.sliceId,
        existingSliceIds: (0, task_pair_creation_1.collectExistingWorkIds)(repositoryRoot, planningRoot, "governed")
    });
    const sliceRoot = (0, work_routing_1.resolvePlanningDestinationSync)(repositoryRoot, {
        planningRoot,
        level: "governed",
        sliceId: identity.sliceId
    });
    const sliceOverviewTarget = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, node_path_1.default.posix.join(sliceRoot.repositoryRelativePath, "slice-overview.md"));
    const routedSpecIndex = (0, slice_generation_1.routeContributorsToGovernedSlice)(sourceEvidence.indexDocument, identity.contributors, identity.implementationOrder, identity.sliceSlug, identity.sliceId, sliceOverviewTarget.repositoryRelativePath);
    const routedSpecIndexContents = (0, spec_registry_1.renderSpecIndexDocument)(routedSpecIndex);
    const registryChanged = registryRoutingAuthorized
        && (0, governed_overview_1.hasGovernedRoutingChanges)(sourceEvidence.indexDocument, routedSpecIndex, identity.contributors);
    const policy = (0, policy_resolution_1.resolveIndependentTaskPolicy)({
        agentMode: {
            ...request.agentModeResolution,
            sessionOverride: request.agentMode ?? request.agentModeResolution?.sessionOverride
        },
        evidenceProfile: {
            ...request.evidenceProfileResolution,
            parent: request.evidenceProfile ?? request.evidenceProfileResolution?.parent
        }
    });
    const overviewContents = (0, governed_overview_1.renderGovernedSliceOverview)({
        sliceId: identity.sliceId,
        sliceSlug: identity.sliceSlug,
        implementationOrder: identity.implementationOrder,
        initiativeId: sourceEvidence.initiativeId,
        planningDepth: sourceEvidence.planningDepth,
        specifications,
        defaultAgentMode: policy.agentMode.value,
        defaultAgentModeSource: policy.agentMode.source,
        defaultEvidenceProfile: policy.evidenceProfile.value,
        defaultEvidenceProfileSource: policy.evidenceProfile.source
    });
    if (sliceOverviewTarget.exists
        && (!registryRoutingAuthorized
            ||
                !node_fs_1.default.statSync(sliceOverviewTarget.runtimePath).isFile()
            || node_fs_1.default.readFileSync(sliceOverviewTarget.runtimePath, "utf8") !== overviewContents)) {
        throw new StructuredWorkCreationError("destination-conflict", `Governed slice overview destination '${sliceOverviewTarget.repositoryRelativePath}' already exists with conflicting content.`);
    }
    const writes = [
        ...(!sliceOverviewTarget.exists
            ? [{ path: sliceOverviewTarget.repositoryRelativePath, contents: overviewContents }]
            : []),
        ...(registryChanged
            ? [{
                    path: sourceEvidence.indexTarget.repositoryRelativePath,
                    contents: routedSpecIndexContents
                }]
            : [])
    ];
    const preconditions = (0, task_pair_creation_1.dedupePreconditions)([
        ...(0, task_pair_creation_1.collectCreationPreconditions)(repositoryRoot, specifications, sliceOverviewTarget.repositoryRelativePath),
        (0, mutation_preconditions_1.captureDestinationPresencePreconditionSync)(sourceEvidence.indexTarget),
        (0, mutation_preconditions_1.captureContentRevisionPreconditionSync)(sourceEvidence.indexTarget)
    ]);
    const expected = preconditions.map((precondition) => ({
        path: precondition.repositoryRelativePath,
        kind: precondition.kind,
        expectedState: precondition.kind === "content-revision"
            ? precondition.expectedRevision
            : precondition.expectedPresence
    }));
    const result = {
        workflowLevel: "governed",
        workflowLevelSource: level.source,
        sliceId: identity.sliceId,
        sliceIdGenerated: identity.generated,
        implementationOrder: identity.implementationOrder,
        sliceSlug: identity.sliceSlug,
        initiativeId: sourceEvidence.initiativeId,
        sliceOverviewPath: sliceOverviewTarget.repositoryRelativePath,
        specifications,
        defaultAgentMode: policy.agentMode.value,
        defaultAgentModeSource: policy.agentMode.source,
        defaultEvidenceProfile: policy.evidenceProfile.value,
        defaultEvidenceProfileSource: policy.evidenceProfile.source,
        expected,
        intendedPaths: writes.map((write) => write.path),
        changedPaths: [],
        writeOutcome: "previewed",
        transactionId: null,
        conflicts: [],
        recoveryPath: null,
        failure: null,
        nextAction: "Apply this preview to create the Governed numbered slice root."
    };
    exports.plans.set(result, {
        repositoryRoot,
        writes,
        preconditions
    });
    return result;
}
function previewWorkOverviewCreationSync(request, producerLevel) {
    const repositoryRoot = (0, governed_overview_1.requireRepositoryRoot)(request.repositoryRoot);
    const specificationPaths = (0, governed_overview_1.normalizeSpecificationPaths)(request.specificationPaths);
    const levelInput = {
        explicit: request.level,
        parent: request.parentLevel,
        project: request.projectLevel,
        repository: request.repositoryLevel,
        user: request.userLevel,
        recommendation: request.recommendation,
        recommendationAccepted: request.recommendationAccepted,
        specificationCount: specificationPaths.length,
        interactive: false
    };
    const level = (0, work_routing_1.resolveWorkflowLevel)(levelInput);
    if (level.level !== producerLevel) {
        throw new StructuredWorkCreationError("unsupported-level", `${(0, governed_overview_1.workflowLevelLabel)(producerLevel)} overview creation cannot create '${level.level}' work. Use the level-specific producer.`);
    }
    const specifications = [...(0, work_routing_1.normalizeSpecificationReferencesSync)(repositoryRoot, {
            level: producerLevel,
            specificationPaths
        })].sort((left, right) => left.specId.localeCompare(right.specId));
    const planningRoot = request.planningRoot ?? ".day-shift/planning";
    const rootContext = producerLevel === "structured"
        ? "structured-root"
        : "structured-root";
    const inventoryCollectionPath = node_path_1.default.posix.join(planningRoot.replace(/\\/g, "/"), producerLevel);
    let rootInventory;
    try {
        rootInventory = (0, ordered_root_identity_1.inspectOrderedRootCollectionSync)({
            repositoryRoot,
            collectionPath: inventoryCollectionPath,
            context: rootContext
        });
    }
    catch (error) {
        throw (0, task_rendering_1.normalizeOrderedRootCreationError)(error);
    }
    const identity = (0, work_routing_1.allocateWorkIdentity)({
        level: producerLevel,
        specificationReferences: specifications,
        requestedWorkId: request.workId,
        existingWorkIds: rootInventory.stableIds
    });
    if (identity.workId === null) {
        throw new StructuredWorkCreationError("invalid-request", `${(0, governed_overview_1.workflowLevelLabel)(producerLevel)} work identity allocation did not return a work identity.`);
    }
    let sourceOrderEvidence;
    try {
        sourceOrderEvidence = producerLevel === "structured"
            ? (0, task_rendering_1.collectStructuredSourceImplementationOrderEvidence)(repositoryRoot, specifications)
            : { orders: [], registryPath: null };
    }
    catch (error) {
        throw (0, task_rendering_1.normalizeOrderedRootCreationError)(error);
    }
    let allocation;
    try {
        allocation = (0, ordered_root_identity_1.allocateOrderedRoot)({
            context: rootContext,
            stableId: identity.workId,
            requestedOrder: request.implementationOrder,
            inheritedOrders: sourceOrderEvidence.orders,
            inventory: rootInventory
        });
    }
    catch (error) {
        throw (0, task_rendering_1.normalizeOrderedRootCreationError)(error);
    }
    const workRoot = (0, work_routing_1.resolvePlanningDestinationSync)(repositoryRoot, {
        planningRoot,
        level: producerLevel,
        workId: identity.workId,
        implementationOrder: allocation.implementationOrder
    });
    const overviewTarget = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, node_path_1.default.posix.join(workRoot.repositoryRelativePath, "overview.md"));
    if (overviewTarget.exists) {
        throw new StructuredWorkCreationError("destination-conflict", `${(0, governed_overview_1.workflowLevelLabel)(producerLevel)} overview destination '${overviewTarget.repositoryRelativePath}' already exists.`);
    }
    const policy = (0, policy_resolution_1.resolveIndependentTaskPolicy)({
        agentMode: {
            ...request.agentModeResolution,
            sessionOverride: request.agentMode ?? request.agentModeResolution?.sessionOverride
        },
        evidenceProfile: {
            ...request.evidenceProfileResolution,
            parent: request.evidenceProfile ?? request.evidenceProfileResolution?.parent
        }
    });
    const preconditions = (0, task_pair_creation_1.dedupePreconditions)([
        ...(0, task_pair_creation_1.collectCreationPreconditions)(repositoryRoot, specifications, overviewTarget.repositoryRelativePath),
        ...rootInventory.artifactPaths.map((artifactPath) => (0, mutation_preconditions_1.captureContentRevisionPreconditionSync)((0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, artifactPath))),
        ...(sourceOrderEvidence.registryPath === null
            ? []
            : [(0, mutation_preconditions_1.captureContentRevisionPreconditionSync)((0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, sourceOrderEvidence.registryPath))])
    ]);
    const expected = preconditions.map((precondition) => ({
        path: precondition.repositoryRelativePath,
        kind: precondition.kind,
        expectedState: precondition.kind === "content-revision"
            ? precondition.expectedRevision
            : precondition.expectedPresence
    }));
    const overviewContents = (0, governed_overview_1.renderWorkOverview)({
        workflowLevel: producerLevel,
        workId: identity.workId,
        implementationOrder: allocation.implementationOrder,
        specifications,
        defaultAgentMode: policy.agentMode.value,
        defaultAgentModeSource: policy.agentMode.source,
        defaultEvidenceProfile: policy.evidenceProfile.value,
        defaultEvidenceProfileSource: policy.evidenceProfile.source
    });
    const result = {
        workflowLevel: producerLevel,
        workflowLevelSource: level.source,
        workId: identity.workId,
        workIdGenerated: identity.generated,
        workIdCollisionOrdinal: identity.collisionOrdinal,
        implementationOrder: allocation.implementationOrder,
        implementationOrderSource: allocation.implementationOrderSource,
        orderedRootName: allocation.orderedRootName,
        rootInventoryFingerprint: rootInventory.fingerprint,
        overviewPath: overviewTarget.repositoryRelativePath,
        specifications,
        defaultAgentMode: policy.agentMode.value,
        defaultAgentModeSource: policy.agentMode.source,
        defaultEvidenceProfile: policy.evidenceProfile.value,
        defaultEvidenceProfileSource: policy.evidenceProfile.source,
        expected,
        intendedPaths: [overviewTarget.repositoryRelativePath],
        changedPaths: [],
        writeOutcome: "previewed",
        transactionId: null,
        conflicts: [],
        recoveryPath: null,
        failure: null,
        nextAction: `Apply this preview to create the ${(0, governed_overview_1.workflowLevelLabel)(producerLevel)} overview.`
    };
    exports.plans.set(result, {
        repositoryRoot,
        writes: [{ path: overviewTarget.repositoryRelativePath, contents: overviewContents }],
        preconditions,
        inventoryGuard: {
            context: rootContext,
            collectionPath: inventoryCollectionPath,
            fingerprint: rootInventory.fingerprint
        }
    });
    return result;
}
function applyStructuredWorkCreationSync(preview, options = {}) {
    return applyWorkOverviewCreationSync(preview, options);
}
function applyGovernedWorkCreationSync(preview, options = {}) {
    const plan = exports.plans.get(preview);
    if (plan === undefined || preview.writeOutcome !== "previewed") {
        throw new StructuredWorkCreationError("stale-preview", "Governed slice creation apply requires the original unused in-process preview. Refresh the preview.");
    }
    exports.plans.delete(preview);
    if (plan.writes.length === 0) {
        const validation = (0, mutation_preconditions_1.revalidateMutationPreconditionsSync)(plan.preconditions);
        if (!validation.ok) {
            return {
                ...preview,
                writeOutcome: "conflict",
                conflicts: validation.conflicts,
                nextAction: (0, governed_overview_1.nextActionForGovernedOutcome)("conflict")
            };
        }
        return {
            ...preview,
            writeOutcome: "no-write",
            nextAction: "Declare and create phases beneath the Governed slice overview."
        };
    }
    const transaction = (0, repository_transaction_1.executeRepositoryTransactionSync)(plan.repositoryRoot, {
        writes: plan.writes,
        preconditions: plan.preconditions
    }, options.transaction);
    return {
        ...preview,
        writeOutcome: transaction.outcome,
        changedPaths: transaction.entries
            .slice(0, transaction.canonicalWrites)
            .map((entry) => entry.path),
        transactionId: transaction.transactionId,
        conflicts: transaction.conflicts,
        recoveryPath: transaction.outcome === "incomplete" ? transaction.transactionPath : null,
        failure: transaction.failure,
        nextAction: transaction.outcome === "committed" || transaction.outcome === "no-write"
            ? "Declare and create phases beneath the Governed slice overview."
            : (0, governed_overview_1.nextActionForGovernedOutcome)(transaction.outcome)
    };
}
function applyWorkOverviewCreationSync(preview, options = {}) {
    const plan = exports.plans.get(preview);
    if (plan === undefined || preview.writeOutcome !== "previewed") {
        throw new StructuredWorkCreationError("stale-preview", `${(0, governed_overview_1.workflowLevelLabel)(preview.workflowLevel)} work creation apply requires the original unused in-process preview. Refresh the preview.`);
    }
    exports.plans.delete(preview);
    if (plan.inventoryGuard !== undefined) {
        let observedFingerprint;
        try {
            observedFingerprint = (0, ordered_root_identity_1.inspectOrderedRootCollectionSync)({
                repositoryRoot: plan.repositoryRoot,
                collectionPath: plan.inventoryGuard.collectionPath,
                context: plan.inventoryGuard.context
            }).fingerprint;
        }
        catch {
            observedFingerprint = "invalid-inventory";
        }
        if (observedFingerprint !== plan.inventoryGuard.fingerprint) {
            return {
                ...preview,
                writeOutcome: "conflict",
                conflicts: [(0, task_rendering_1.inventoryConflict)(plan.inventoryGuard.collectionPath, plan.inventoryGuard.fingerprint, observedFingerprint)],
                nextAction: `Refresh the ${(0, governed_overview_1.workflowLevelLabel)(preview.workflowLevel)} creation preview after the ordered-root inventory changed.`
            };
        }
    }
    const transaction = (0, repository_transaction_1.executeRepositoryTransactionSync)(plan.repositoryRoot, {
        writes: plan.writes,
        preconditions: plan.preconditions
    }, options.transaction);
    const changedPaths = transaction.entries
        .slice(0, transaction.canonicalWrites)
        .map((entry) => entry.path);
    return {
        ...preview,
        writeOutcome: transaction.outcome,
        changedPaths,
        transactionId: transaction.transactionId,
        conflicts: transaction.conflicts,
        recoveryPath: transaction.outcome === "incomplete" ? transaction.transactionPath : null,
        failure: transaction.failure,
        nextAction: (0, governed_overview_1.nextActionForOutcome)(transaction.outcome, preview.workflowLevel)
    };
}
