"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.projectPlanningTopologyEvidence = projectPlanningTopologyEvidence;
exports.resolveRequiredPromptReference = resolveRequiredPromptReference;
exports.resolveScope = resolveScope;
exports.collectArtifactsForScope = collectArtifactsForScope;
exports.readArtifactRecord = readArtifactRecord;
exports.inspectTaskCommandArtifactTarget = inspectTaskCommandArtifactTarget;
exports.readArtifactIfExists = readArtifactIfExists;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const config_layer_resolution_1 = require("../../config/config-layer-resolution");
const errors_1 = require("../../errors");
const paths_1 = require("../../paths");
const artifact_policy_projection_1 = require("../artifact-policy-projection");
const planning_document_utils_1 = require("../planning-document-utils");
const document_support_1 = require("./document-support");
function projectPlanningTopologyEvidence(record) {
    const policy = (0, artifact_policy_projection_1.projectArtifactPolicy)(record.document.rawText);
    const topology = policy.topology;
    return {
        workflowTopology: topology,
        taskSummaryReviewBoundary: topology?.taskSummaryReviewBoundary ?? null,
        reconciliationArtifactKind: topology?.reconciliationArtifactKind ?? null,
        reconciliationRequired: topology?.reconciliationRequired ?? null,
        organizationParents: topology?.organizationParents ?? [],
        projectReviewCapability: topology?.projectReviewCapability ?? null,
        blockingFindings: topology === null ? policy.blockingFindings : []
    };
}
function resolveRequiredPromptReference(repositoryRoot, config, requestedPromptPath) {
    return (0, config_layer_resolution_1.resolveRequiredPromptReference)({
        repositoryRoot,
        config,
        requestedPromptPath
    });
}
function resolveScope(repositoryRoot, inputPath, allowDirectory) {
    const parsedPath = (0, paths_1.parseRepositoryRelativePath)(inputPath);
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, parsedPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        throw (0, errors_1.createUsageError)(`Planning scope path '${parsedPath.normalizedPath}' does not exist.`, [
            "Pass an existing repository-relative planning path."
        ]);
    }
    const stats = node_fs_1.default.statSync(absolutePath);
    if (stats.isDirectory()) {
        if (!allowDirectory) {
            throw (0, errors_1.createUsageError)(`Artifact path '${parsedPath.normalizedPath}' must point to a planning artifact file.`, [
                "Use a repository-relative path to a slice/phase/milestone/task/review artifact."
            ]);
        }
        return {
            path: parsedPath.normalizedPath,
            absolutePath,
            kind: "planning-root"
        };
    }
    const record = readArtifactRecord(repositoryRoot, parsedPath.normalizedPath);
    return {
        path: parsedPath.normalizedPath,
        absolutePath,
        kind: record.artifactType
    };
}
function collectArtifactsForScope(repositoryRoot, scope) {
    if (scope.kind !== "planning-root"
        && scope.kind !== "work_overview"
        && scope.kind !== "slice_overview"
        && scope.kind !== "phase_overview") {
        const selectedRecord = readArtifactRecord(repositoryRoot, scope.path);
        const pairedPath = selectedRecord.artifactType === "task_definition"
            ? (0, document_support_1.pairedImplementationSummaryPath)(selectedRecord.path)
            : selectedRecord.artifactType === "implementation_summary"
                ? (0, document_support_1.pairedTaskDefinitionPath)(selectedRecord.path)
                : null;
        const pairedRecord = pairedPath === null
            ? null
            : readArtifactIfExists(repositoryRoot, pairedPath);
        return pairedRecord === null
            ? [selectedRecord]
            : [selectedRecord, pairedRecord].sort((left, right) => left.path.localeCompare(right.path));
    }
    const artifactPaths = [];
    const stack = [
        scope.kind === "planning-root"
            ? scope.absolutePath
            : node_path_1.default.dirname(scope.absolutePath)
    ];
    while (stack.length > 0) {
        const currentPath = stack.pop();
        if (currentPath === undefined) {
            continue;
        }
        const stats = node_fs_1.default.statSync(currentPath);
        if (stats.isFile()) {
            const relativePath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, currentPath));
            if ((0, document_support_1.isRecognizedArtifactFilename)(relativePath)) {
                artifactPaths.push(relativePath);
            }
            continue;
        }
        const children = node_fs_1.default.readdirSync(currentPath);
        for (const child of children) {
            stack.push(node_path_1.default.join(currentPath, child));
        }
    }
    return artifactPaths
        .sort((left, right) => left.localeCompare(right))
        .map((artifactPath) => readArtifactRecord(repositoryRoot, artifactPath));
}
function readArtifactRecord(repositoryRoot, artifactPath) {
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(artifactPath));
    const document = (0, document_support_1.parseMarkdownDocument)(artifactPath, node_fs_1.default.readFileSync(absolutePath, "utf8"));
    const artifactType = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "artifact_type")?.trim() ?? null;
    if (!(0, document_support_1.isPlanningArtifactType)(artifactType)) {
        throw (0, errors_1.createInvalidConfigError)(`Planning artifact '${artifactPath}' has unsupported artifact_type '${artifactType ?? "(missing)"}'.`, ["Expected a supported planning artifact with YAML front matter."]);
    }
    return {
        path: artifactPath,
        artifactType,
        status: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "status")?.trim() ?? null,
        planningDepth: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "planning_depth")?.trim() ?? null,
        readiness: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "readiness")?.trim() ?? null,
        implementationStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "implementation_status")?.trim() ?? null,
        reconciliationStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "reconciliation_status")?.trim() ?? null,
        upstreamTaskDefinitionPath: (0, planning_document_utils_1.readUpstreamField)(document.frontMatterLines, "task_definition")?.trim() ?? null,
        upstreamMilestoneOverviewPath: (0, planning_document_utils_1.readUpstreamField)(document.frontMatterLines, "milestone_overview")?.trim() ?? null,
        document
    };
}
function inspectTaskCommandArtifactTarget(repositoryRoot, requestedPath) {
    if (requestedPath === null || requestedPath === undefined || requestedPath.trim() === "") {
        return {
            requestedPath: requestedPath ?? null,
            normalizedPath: null,
            exists: false,
            artifactType: null,
            taskIdentity: null,
            evidenceProfile: null,
            callable: false,
            reason: "No task-definition artifact path was supplied."
        };
    }
    let normalizedPath;
    let absolutePath;
    try {
        const parsed = (0, paths_1.parseRepositoryRelativePath)(requestedPath);
        normalizedPath = parsed.normalizedPath;
        absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, parsed);
    }
    catch (error) {
        return {
            requestedPath,
            normalizedPath: null,
            exists: false,
            artifactType: null,
            taskIdentity: null,
            evidenceProfile: null,
            callable: false,
            reason: `Task command target is not a valid repository-relative path: ${error instanceof Error ? error.message : String(error)}`
        };
    }
    if (!node_fs_1.default.existsSync(absolutePath) || !node_fs_1.default.statSync(absolutePath).isFile()) {
        return {
            requestedPath,
            normalizedPath,
            exists: false,
            artifactType: null,
            taskIdentity: null,
            evidenceProfile: null,
            callable: false,
            reason: `Task command target '${normalizedPath}' is not an existing regular file.`
        };
    }
    try {
        const record = readArtifactRecord(repositoryRoot, normalizedPath);
        const evidenceProfile = (0, artifact_policy_projection_1.projectArtifactPolicy)(record.document.rawText).evidenceProfile;
        return {
            requestedPath,
            normalizedPath,
            exists: true,
            artifactType: record.artifactType,
            taskIdentity: (0, planning_document_utils_1.readTopLevelField)(record.document.frontMatterLines, "task")?.trim() ?? null,
            evidenceProfile,
            callable: record.artifactType === "task_definition",
            reason: record.artifactType === "task_definition"
                ? "Target is a materialized task_definition artifact."
                : `Task commands require artifact_type task_definition; '${normalizedPath}' is '${record.artifactType}'.`
        };
    }
    catch (error) {
        return {
            requestedPath,
            normalizedPath,
            exists: true,
            artifactType: null,
            taskIdentity: null,
            evidenceProfile: null,
            callable: false,
            reason: `Task command target '${normalizedPath}' is not a readable supported planning artifact: ${error instanceof Error ? error.message : String(error)}`
        };
    }
}
function readArtifactIfExists(repositoryRoot, artifactPath) {
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(artifactPath));
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return null;
    }
    return readArtifactRecord(repositoryRoot, artifactPath);
}
