import { sshExec } from "../../utils/ssh.js";
import { raw } from "../../utils/sshCommand.js";
import { debugLog } from "../../utils/logger.js";
import { isSafeMode } from "../../utils/safeMode.js";
import { PLUGINS_NODE_MODULES } from "../../utils/paths.js";
import { getPluginRegistry } from "../../plugin/registry.js";
import { resolvePluginHandler } from "../../plugin/handlerResolver.js";
import { join } from "path";
const PLUGIN_FIX_PREFIX = "plugin:";
export function isPluginFixCommand(fixCommand) {
    return typeof fixCommand === "string" && fixCommand.startsWith(PLUGIN_FIX_PREFIX);
}
export function parsePluginFixCommand(fixCommand) {
    if (!fixCommand.startsWith(PLUGIN_FIX_PREFIX))
        return null;
    const parts = fixCommand.split(":");
    if (parts.length < 3)
        return null;
    const pluginName = parts[1];
    const handlerPath = parts.slice(2).join(":");
    if (!pluginName || !handlerPath)
        return null;
    return { pluginName, handlerPath };
}
export function getPluginFixMetadata(failedCheckIds, appliedCheckIds) {
    const registry = getPluginRegistry();
    const failedSet = new Set(failedCheckIds);
    const appliedSet = new Set(appliedCheckIds);
    const backupPaths = [];
    const pluginNames = new Set();
    for (const [, entry] of registry) {
        if (entry.status !== "loaded" || !entry.manifest.fixes)
            continue;
        for (const fix of entry.manifest.fixes) {
            if (failedSet.has(fix.checkId) && fix.backupPaths) {
                backupPaths.push(...fix.backupPaths);
            }
            if (appliedSet.has(fix.checkId)) {
                pluginNames.add(entry.manifest.name);
            }
        }
    }
    return { backupPaths, pluginNames: [...pluginNames] };
}
export function getPluginBackupPaths(failedCheckIds) {
    return getPluginFixMetadata(failedCheckIds, []).backupPaths;
}
export function getAppliedPluginNames(appliedCheckIds) {
    return getPluginFixMetadata([], appliedCheckIds).pluginNames;
}
export async function executePluginFix(ip, checkId, pluginName, handlerPath, dryRun) {
    const startMs = Date.now();
    if (isSafeMode()) {
        return { success: false, error: "SAFE_MODE active — plugin fix blocked" };
    }
    if (dryRun) {
        return { success: true };
    }
    const registry = getPluginRegistry();
    const entry = registry.get(pluginName);
    if (!entry || entry.status !== "loaded") {
        return { success: false, error: `Plugin "${pluginName}" not found or failed to load` };
    }
    const pluginDir = join(PLUGINS_NODE_MODULES, pluginName);
    let handlerFn;
    try {
        handlerFn = await resolvePluginHandler(pluginDir, handlerPath);
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return { success: false, error: `Failed to import fix handler: ${msg}` };
    }
    const ctx = {
        ip,
        ssh: async (command, options) => {
            return sshExec(ip, raw(command), options);
        },
        logger: {
            info: (msg) => { if (debugLog)
                console.log(`[plugin-fix:${pluginName}] ${msg}`); },
            warn: (msg) => { if (debugLog)
                console.log(`[plugin-fix:${pluginName}] WARN: ${msg}`); },
            error: (msg) => console.error(`[plugin-fix:${pluginName}] ERROR: ${msg}`),
        },
        dryRun,
        manifest: entry.manifest,
    };
    try {
        const result = await handlerFn(checkId, ctx);
        const durationMs = Date.now() - startMs;
        return {
            success: result.success,
            error: result.error,
            modifiedFiles: result.modifiedFiles,
            executionLog: {
                checkId,
                command: `plugin:${pluginName}:${handlerPath}`,
                stdout: result.success ? "plugin fix applied" : "",
                stderr: result.error ?? "",
                durationMs,
                success: result.success,
            },
        };
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        const durationMs = Date.now() - startMs;
        return {
            success: false,
            error: `Plugin fix handler threw: ${msg}`,
            executionLog: {
                checkId,
                command: `plugin:${pluginName}:${handlerPath}`,
                stdout: "",
                stderr: msg,
                durationMs,
                success: false,
            },
        };
    }
}
//# sourceMappingURL=pluginFix.js.map