"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.runDoctorEnvironmentChecks = runDoctorEnvironmentChecks;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_child_process_1 = require("node:child_process");
const runtime_contract_1 = require("../runtime/runtime-contract");
const config_store_1 = require("../config/config-store");
const config_contract_1 = require("../config/config-contract");
const local_paths_1 = require("./local-paths");
function runDoctorEnvironmentChecks(input) {
    const { repositoryRoot, detectionSource, findings } = input;
    const checks = [];
    checks.push(runRepositoryRootCheck(detectionSource, findings));
    const configCheckResult = runConfigParsingCheck(repositoryRoot, findings);
    checks.push(configCheckResult.check);
    const repositoryContext = (0, runtime_contract_1.createRepositoryContext)({ root: repositoryRoot, detectionSource }, false);
    const resolvedConfig = configCheckResult.resolvedConfig
        ?? (0, config_contract_1.resolveDayShiftConfig)({ repositoryContext });
    checks.push(runPlanningRootCheck(resolvedConfig, findings));
    checks.push(runAgentEntrypointCheck(resolvedConfig, findings));
    checks.push(runTemplateResolutionCheck(repositoryRoot, findings));
    checks.push(runGitAvailabilityCheck(repositoryRoot, findings));
    return {
        checks,
        resolvedConfig
    };
}
function runRepositoryRootCheck(detectionSource, findings) {
    if (detectionSource === "cwd") {
        findings.push({
            code: "REPOSITORY_ROOT_UNVERIFIED",
            message: "Could not verify repository root from .day-shift markers or .git; run from a Day Shift repository root.",
            severity: "error"
        });
        return {
            id: "repository-root-detection",
            status: "error",
            message: "Repository root could not be verified from known markers."
        };
    }
    return {
        id: "repository-root-detection",
        status: "ok",
        message: `Repository root detected from ${detectionSource}.`
    };
}
function runConfigParsingCheck(repositoryRoot, findings) {
    const configPath = ".day-shift/config.toml";
    if (!node_fs_1.default.existsSync(node_path_1.default.join(repositoryRoot, configPath))) {
        findings.push({
            code: "CONFIG_MISSING",
            message: "Missing .day-shift/config.toml; run 'day-shift init' to scaffold baseline workspace config.",
            severity: "error",
            path: configPath
        });
        return {
            check: {
                id: "config-parsing",
                status: "error",
                message: "Workspace config file is missing."
            },
            resolvedConfig: null
        };
    }
    try {
        const configResult = (0, config_store_1.readResolvedConfig)((0, runtime_contract_1.createRepositoryContext)({ root: repositoryRoot, detectionSource: "config-toml" }, false));
        return {
            check: {
                id: "config-parsing",
                status: "ok",
                message: "Workspace config parsed successfully."
            },
            resolvedConfig: configResult.resolved
        };
    }
    catch (error) {
        const errorMessage = error instanceof Error ? error.message : "Could not parse config.";
        findings.push({
            code: "CONFIG_INVALID",
            message: errorMessage,
            severity: "error",
            path: configPath
        });
        return {
            check: {
                id: "config-parsing",
                status: "error",
                message: "Workspace config is invalid."
            },
            resolvedConfig: null
        };
    }
}
function runPlanningRootCheck(resolvedConfig, findings) {
    const planningPath = resolvedConfig.derived.planningRootPath;
    if (!(0, local_paths_1.isExistingDirectory)(planningPath)) {
        findings.push({
            code: "PLANNING_ROOT_MISSING",
            message: "Planning root is missing; run 'day-shift init' to scaffold .day-shift/planning/.",
            severity: "error",
            path: (0, local_paths_1.toRepositoryRelativePath)(resolvedConfig.derived.repositoryRoot, planningPath)
        });
        return {
            id: "planning-root-presence",
            status: "error",
            message: "Planning root is missing."
        };
    }
    return {
        id: "planning-root-presence",
        status: "ok",
        message: "Planning root is present."
    };
}
function runAgentEntrypointCheck(resolvedConfig, findings) {
    const agentEntrypointPath = resolvedConfig.derived.agentEntrypointPath;
    if (!(0, local_paths_1.isExistingFile)(agentEntrypointPath)) {
        findings.push({
            code: "AGENT_ENTRYPOINT_MISSING",
            message: "Agent entrypoint is missing; run 'day-shift init' to scaffold .day-shift/agents.md.",
            severity: "error",
            path: (0, local_paths_1.toRepositoryRelativePath)(resolvedConfig.derived.repositoryRoot, agentEntrypointPath)
        });
        return {
            id: "agent-entrypoint-availability",
            status: "error",
            message: "Agent entrypoint is missing."
        };
    }
    return {
        id: "agent-entrypoint-availability",
        status: "ok",
        message: "Agent entrypoint is present."
    };
}
function runTemplateResolutionCheck(repositoryRoot, findings) {
    const templatesRelativePath = ".day-shift/templates";
    const templatesPath = node_path_1.default.join(repositoryRoot, templatesRelativePath);
    if (!(0, local_paths_1.isExistingDirectory)(templatesPath)) {
        findings.push({
            code: "TEMPLATES_ROOT_MISSING",
            message: "Template root is missing; run 'day-shift init' to scaffold .day-shift/templates/.",
            severity: "error",
            path: templatesRelativePath
        });
        return {
            id: "template-resolution",
            status: "error",
            message: "Template root directory is missing."
        };
    }
    if (!directoryContainsFiles(templatesPath)) {
        findings.push({
            code: "TEMPLATES_UNAVAILABLE",
            message: "Template root exists but contains no template files.",
            severity: "error",
            path: templatesRelativePath
        });
        return {
            id: "template-resolution",
            status: "error",
            message: "Template root contains no files."
        };
    }
    return {
        id: "template-resolution",
        status: "ok",
        message: "Template root resolves to a directory with template files."
    };
}
function runGitAvailabilityCheck(repositoryRoot, findings) {
    const gitProbe = (0, node_child_process_1.spawnSync)("git", ["--version"], {
        cwd: repositoryRoot,
        encoding: "utf8",
        stdio: ["ignore", "pipe", "pipe"]
    });
    if (gitProbe.error !== undefined || gitProbe.status !== 0) {
        findings.push({
            code: "GIT_UNAVAILABLE",
            message: "Git is unavailable in this environment; install Git and ensure it is on PATH.",
            severity: "error"
        });
        return {
            id: "git-availability",
            status: "error",
            message: "Git command is unavailable."
        };
    }
    return {
        id: "git-availability",
        status: "ok",
        message: (gitProbe.stdout ?? "").trim() || "Git is available."
    };
}
function directoryContainsFiles(directoryPath) {
    const entries = node_fs_1.default.readdirSync(directoryPath, { withFileTypes: true });
    for (const entry of entries) {
        if (entry.isFile()) {
            return true;
        }
        if (entry.isDirectory() && directoryContainsFiles(node_path_1.default.join(directoryPath, entry.name))) {
            return true;
        }
    }
    return false;
}
