import path from "node:path";
import { promises as fs } from "node:fs";
import { pathExists, readJson, writeText } from "../utils/fs.js";
export const MACHINE_ADVISORY_ARTIFACT_TYPE = "kiwi-control/machine-advisory";
export const MACHINE_ADVISORY_VERSION = 3;
export const MACHINE_ADVISORY_CACHE_TTL_MS = 60_000;
export function advisoryCachePath(homeRoot) {
    return path.join(homeRoot, ".kiwi-control", "cache", "machine-advisory.json");
}
export async function writeMachineAdvisoryCache(homeRoot, advisory) {
    const cachePath = advisoryCachePath(homeRoot);
    await fs.mkdir(path.dirname(cachePath), { recursive: true });
    await writeText(cachePath, `${JSON.stringify(advisory, null, 2)}\n`);
}
export async function loadMachineAdvisoryFromCache(homeRoot, now, options = {}) {
    const cached = await readCachedMachineAdvisory(homeRoot);
    if (!cached) {
        return null;
    }
    if (options.forceStale) {
        return {
            ...cached,
            stale: true,
            note: options.note ?? cached.note
        };
    }
    const age = now.getTime() - new Date(cached.updatedAt).getTime();
    if (age < MACHINE_ADVISORY_CACHE_TTL_MS && !cached.stale) {
        return { ...cached, stale: false };
    }
    return null;
}
export async function loadMachineAdvisorySectionFromCache(section, homeRoot, now) {
    const cached = await readCachedMachineAdvisory(homeRoot);
    if (!cached) {
        return null;
    }
    const age = now.getTime() - new Date(cached.updatedAt).getTime();
    if (!Number.isFinite(age) || age < 0) {
        return null;
    }
    const advisory = age < MACHINE_ADVISORY_CACHE_TTL_MS && !cached.stale
        ? { ...cached, stale: false }
        : markMachineAdvisoryCached(cached, now);
    return sectionFromMachineAdvisory(section, advisory);
}
export function sectionFromMachineAdvisory(section, advisory) {
    switch (section) {
        case "inventory":
            return { section, meta: advisory.sections.inventory, data: advisory.inventory };
        case "mcpInventory":
            return { section, meta: advisory.sections.mcpInventory, data: advisory.mcpInventory };
        case "optimizationLayers":
            return { section, meta: advisory.sections.optimizationLayers, data: advisory.optimizationLayers };
        case "setupPhases":
            return { section, meta: advisory.sections.setupPhases, data: advisory.setupPhases };
        case "configHealth":
            return { section, meta: advisory.sections.configHealth, data: advisory.configHealth };
        case "usage":
            return { section, meta: advisory.sections.usage, data: advisory.usage };
        case "guidance":
            return { section, meta: advisory.sections.guidance, data: advisory.guidance };
    }
}
export function markMachineAdvisoryCached(advisory, now, note = advisory.note) {
    const updatedAt = advisory.updatedAt || now.toISOString();
    return {
        ...advisory,
        stale: true,
        note,
        sections: Object.fromEntries(Object.entries(advisory.sections ?? buildDefaultSectionState(updatedAt)).map(([key, value]) => [
            key,
            value.status === "partial"
                ? value
                : {
                    ...value,
                    status: "cached"
                }
        ]))
    };
}
function buildDefaultSectionState(updatedAt) {
    return {
        inventory: { status: "cached", updatedAt },
        mcpInventory: { status: "cached", updatedAt },
        optimizationLayers: { status: "cached", updatedAt },
        setupPhases: { status: "cached", updatedAt },
        configHealth: { status: "cached", updatedAt },
        usage: { status: "cached", updatedAt },
        guidance: { status: "cached", updatedAt }
    };
}
async function readCachedMachineAdvisory(homeRoot) {
    const cachePath = advisoryCachePath(homeRoot);
    if (!(await pathExists(cachePath))) {
        return null;
    }
    try {
        const cached = await readJson(cachePath);
        if (cached.artifactType !== MACHINE_ADVISORY_ARTIFACT_TYPE || cached.version !== MACHINE_ADVISORY_VERSION) {
            return null;
        }
        return cached;
    }
    catch {
        return null;
    }
}
