import { z } from "zod";
import { getServers } from "../../utils/config.js";
import { fetchServerLogs, fetchServerMetrics } from "../../core/logs.js";
import { isBareServer } from "../../utils/modeGuard.js";
import { getAdapter, resolvePlatform } from "../../adapters/factory.js";
import { resolveServerForMcp, mcpSuccess, mcpError, } from "../utils.js";
import { getErrorMessage, sanitizeStderr } from "../../utils/errorMapper.js";
export const serverLogsSchema = {
    action: z.enum(["logs", "monitor"]).describe("Action: 'logs' fetch recent log lines, 'monitor' fetch CPU/RAM/Disk metrics"),
    server: z.string().optional().describe("Server name or IP. Auto-selected if only one server exists."),
    service: z.enum(["coolify", "docker", "system"]).default("coolify").describe("Log source (only for 'logs' action): 'coolify' container (Coolify servers only), 'docker' service journal, 'system' full journal"),
    lines: z.number().min(1).max(500).default(50).describe("Number of log lines to fetch (only for 'logs' action, default: 50, max: 500)"),
    containers: z.boolean().default(false).describe("Include Docker container list in metrics (only for 'monitor' action)"),
};
// ─── Output Schema ────────────────────────────────────────────────────────────
const serverLogsLogsOutputSchema = z.object({
    server: z.string(),
    ip: z.string(),
    service: z.string(),
    lines: z.number(),
    logs: z.string(),
    suggested_actions: z.array(z.object({ command: z.string(), reason: z.string() })),
});
const serverLogsMonitorOutputSchema = z.object({
    server: z.string(),
    ip: z.string(),
    metrics: z.object({
        cpu: z.object({ percent: z.number() }),
        mem: z.object({ percent: z.number(), total: z.number(), used: z.number() }),
        disk: z.object({ percent: z.number(), total: z.number(), used: z.number() }),
    }),
    containers: z.array(z.object({ id: z.string(), name: z.string(), status: z.string() })).optional(),
    suggested_actions: z.array(z.object({ command: z.string(), reason: z.string() })),
});
export const serverLogsOutputSchema = z.object({
    result: z.discriminatedUnion("action", [
        z.object({ action: z.literal("logs"), ...serverLogsLogsOutputSchema.shape }),
        z.object({ action: z.literal("monitor"), ...serverLogsMonitorOutputSchema.shape }),
    ]),
});
export async function handleServerLogs(params) {
    try {
        const servers = getServers();
        if (servers.length === 0) {
            return mcpError("No servers found", undefined, [
                { command: "kastell init", reason: "Deploy a server first" },
            ]);
        }
        const server = resolveServerForMcp(params, servers);
        if (!server) {
            if (params.server) {
                return mcpError(`Server not found: ${params.server}`, `Available servers: ${servers.map((s) => s.name).join(", ")}`);
            }
            return mcpError("Multiple servers found. Specify which server to use.", `Available: ${servers.map((s) => s.name).join(", ")}`);
        }
        switch (params.action) {
            case "logs": {
                // Resolve default service from adapter (coolify→"coolify", dokploy→"dokploy", bare→"system")
                const platform = resolvePlatform(server);
                const adapter = platform ? getAdapter(platform) : null;
                const defaultService = isBareServer(server) || !adapter
                    ? "system"
                    : adapter.defaultLogService;
                const service = params.service ?? defaultService;
                const lines = params.lines ?? 50;
                // Guard: bare servers cannot read platform service logs
                if (isBareServer(server) && service !== "system" && service !== "docker") {
                    return mcpError(`'${service}' logs not available on bare servers`, "Use service: 'system' or 'docker' for bare servers", [
                        {
                            command: `server_logs { action: 'logs', server: '${server.name}', service: 'system' }`,
                            reason: "View system journal instead",
                        },
                    ]);
                }
                const result = await fetchServerLogs(server.ip, service, lines);
                if (result.error) {
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    server: server.name,
                                    ip: server.ip,
                                    service,
                                    error: result.error,
                                    ...(result.hint ? { hint: result.hint } : {}),
                                    ...(result.logs ? { partial_logs: result.logs } : {}),
                                    suggested_actions: [
                                        { command: `kastell logs ${server.name} --service ${service}`, reason: "Try from CLI for interactive mode" },
                                        { command: `server_info { action: 'health', server: '${server.name}' }`, reason: "Check if server is reachable" },
                                    ],
                                }) }],
                        isError: true,
                    };
                }
                const suggestedActions = [
                    { command: `server_logs { action: 'monitor', server: '${server.name}' }`, reason: "Check system metrics" },
                ];
                if (lines < 200) {
                    suggestedActions.unshift({
                        command: `server_logs { action: 'logs', server: '${server.name}', service: '${service}', lines: 200 }`,
                        reason: "Fetch more lines",
                    });
                }
                if (service === "coolify") {
                    suggestedActions.push({
                        command: `server_logs { action: 'logs', server: '${server.name}', service: 'system' }`,
                        reason: "Check system journal",
                    });
                }
                return mcpSuccess({
                    action: "logs",
                    server: server.name,
                    ip: server.ip,
                    service,
                    lines,
                    logs: result.logs,
                    suggested_actions: suggestedActions,
                }, { largeResult: true });
            }
            case "monitor": {
                const includeContainers = isBareServer(server) ? false : (params.containers ?? false);
                const result = await fetchServerMetrics(server.ip, includeContainers);
                if (result.error) {
                    return {
                        content: [{ type: "text", text: JSON.stringify({
                                    server: server.name,
                                    ip: server.ip,
                                    error: result.error,
                                    ...(result.hint ? { hint: result.hint } : {}),
                                    suggested_actions: [
                                        { command: `server_info { action: 'health', server: '${server.name}' }`, reason: "Check if server is reachable" },
                                    ],
                                }) }],
                        isError: true,
                    };
                }
                const suggestedActions = [
                    { command: `server_logs { action: 'logs', server: '${server.name}' }`, reason: "Check recent logs" },
                ];
                if (!includeContainers) {
                    suggestedActions.unshift({
                        command: `server_logs { action: 'monitor', server: '${server.name}', containers: true }`,
                        reason: "Include Docker container list",
                    });
                }
                return mcpSuccess({
                    action: "monitor",
                    server: server.name,
                    ip: server.ip,
                    metrics: result.metrics,
                    ...(result.containers ? { containers: result.containers } : {}),
                    suggested_actions: suggestedActions,
                });
            }
        }
    }
    catch (error) {
        return mcpError(sanitizeStderr(getErrorMessage(error)));
    }
}
//# sourceMappingURL=serverLogs.js.map