import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const BUILTIN_SKILLS_DIR = fileURLToPath(new URL("../../builtin-skills/", import.meta.url));
let recipeCache = null;
function parseFrontmatter(content) {
    const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
    if (!fmMatch)
        return {};
    const fields = {};
    for (const line of fmMatch[1].split("\n")) {
        const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
        if (match)
            fields[match[1]] = match[2].trim();
    }
    return fields;
}
function parseHosts(raw) {
    if (!raw)
        return [];
    return raw
        .split(",")
        .map((h) => h.trim().toLowerCase())
        .filter(Boolean);
}
export function parseCleanupRecipesFromSkill(content, fallbackName) {
    const fm = parseFrontmatter(content);
    const skillName = fm.name || fallbackName;
    const hosts = parseHosts(fm.autoCleanupHosts);
    if (hosts.length === 0)
        return [];
    const recipes = [];
    const blocks = content.matchAll(/```(?:js|javascript)\s+dipclaw:auto-cleanup:([A-Za-z0-9_-]+)\s*\n([\s\S]*?)\n```/g);
    for (const block of blocks) {
        const stage = block[1].trim();
        const script = block[2].trim();
        if (!stage || !script)
            continue;
        recipes.push({ skillName, stage, hosts, script });
    }
    return recipes;
}
export function loadBuiltinPageCleanupRecipes() {
    if (recipeCache)
        return recipeCache;
    if (!fs.existsSync(BUILTIN_SKILLS_DIR)) {
        recipeCache = [];
        return recipeCache;
    }
    recipeCache = fs
        .readdirSync(BUILTIN_SKILLS_DIR)
        .filter((f) => f.endsWith(".md"))
        .flatMap((file) => {
        const filePath = path.join(BUILTIN_SKILLS_DIR, file);
        const content = fs.readFileSync(filePath, "utf-8");
        return parseCleanupRecipesFromSkill(content, path.basename(file, ".md"));
    });
    return recipeCache;
}
function hostMatches(hostname, hosts) {
    return hosts.some((host) => hostname === host || hostname.endsWith(`.${host}`));
}
function cleanupHandled(result) {
    return (!!result &&
        typeof result === "object" &&
        "handled" in result &&
        result.handled === true);
}
export function cleanupRunHandled(run) {
    return run.ok && cleanupHandled(run.result);
}
export function selectBuiltinPageCleanupRecipes(pageUrl, stage) {
    let hostname;
    try {
        hostname = new URL(pageUrl).hostname.toLowerCase();
    }
    catch {
        return [];
    }
    return loadBuiltinPageCleanupRecipes().filter((recipe) => recipe.stage === stage && hostMatches(hostname, recipe.hosts));
}
export async function runBuiltinPageCleanups(page, stage) {
    const recipes = selectBuiltinPageCleanupRecipes(page.url(), stage);
    const runs = [];
    let handled = false;
    for (const recipe of recipes) {
        try {
            const result = await page.evaluate(recipe.script);
            handled ||= cleanupHandled(result);
            runs.push({
                skillName: recipe.skillName,
                stage: recipe.stage,
                ok: true,
                result,
            });
        }
        catch (err) {
            runs.push({
                skillName: recipe.skillName,
                stage: recipe.stage,
                ok: false,
                error: err instanceof Error ? err.message : String(err),
            });
        }
    }
    if (handled) {
        await page.waitForTimeout(100).catch(() => { });
    }
    return runs;
}
//# sourceMappingURL=builtin-page-cleanups.js.map