// tools/tool-usage-report.ts — SPEC-574: Tool usage analytics handler.
// Identifies top tools, low-usage tools, zero-usage tools, and common sequences.
import { usageStore } from '../storage/index.js';
import { readRegisteredToolNames } from './tool-usage-report/registered-tools.js';
const DEFAULT_DAYS = 30;
const SESSION_GAP_MS = 60_000; // 60 seconds — events within this window are "same session"
const TOP_TOOLS_LIMIT = 20;
const LOW_USAGE_MAX = 2;
// ---------------------------------------------------------------------------
// Main handler
// ---------------------------------------------------------------------------
export async function handleToolUsageReport(args) {
    const days = args.days ?? DEFAULT_DAYS;
    const windowStart = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
    const usageLog = await usageStore.getUsageLog();
    const allEvents = usageLog.events;
    // Filter events within the time window
    const windowEvents = allEvents.filter((e) => e.timestamp >= windowStart);
    const callsByTool = countByTool(windowEvents);
    const topTools = buildTopTools(windowEvents, callsByTool, days);
    const lowUsageTools = buildLowUsageTools(callsByTool);
    const registeredTools = await readRegisteredToolNames();
    const zeroUsageTools = buildZeroUsageTools(callsByTool, registeredTools);
    const toolSequences = buildToolSequences(windowEvents);
    const report = formatReport({
        days,
        windowStart,
        topTools,
        lowUsageTools,
        zeroUsageTools,
        toolSequences,
        totalEvents: windowEvents.length,
    });
    return { content: [{ type: 'text', text: report }] };
}
// ---------------------------------------------------------------------------
// Computation helpers
// ---------------------------------------------------------------------------
function countByTool(events) {
    const counts = new Map();
    for (const e of events) {
        counts.set(e.toolName, (counts.get(e.toolName) ?? 0) + 1);
    }
    return counts;
}
function buildTopTools(events, callsByTool, days) {
    const halfWindowMs = (days / 2) * 24 * 60 * 60 * 1000;
    const halfPoint = new Date(Date.now() - halfWindowMs).toISOString();
    // Count calls in first half vs second half of window
    const firstHalf = new Map();
    const secondHalf = new Map();
    for (const e of events) {
        if (e.timestamp < halfPoint) {
            firstHalf.set(e.toolName, (firstHalf.get(e.toolName) ?? 0) + 1);
        }
        else {
            secondHalf.set(e.toolName, (secondHalf.get(e.toolName) ?? 0) + 1);
        }
    }
    const sorted = [...callsByTool.entries()].sort((a, b) => b[1] - a[1]).slice(0, TOP_TOOLS_LIMIT);
    return sorted.map(([name, count]) => {
        const first = firstHalf.get(name) ?? 0;
        const second = secondHalf.get(name) ?? 0;
        let trend = '→';
        if (second > first) {
            trend = '↑';
        }
        else if (second < first) {
            trend = '↓';
        }
        return { name, count, trend };
    });
}
function buildLowUsageTools(callsByTool) {
    return [...callsByTool.entries()]
        .filter(([, count]) => count >= 1 && count <= LOW_USAGE_MAX)
        .map(([name]) => name)
        .sort();
}
function buildZeroUsageTools(callsByTool, registeredTools) {
    return registeredTools.filter((name) => !callsByTool.has(name)).sort();
}
function buildToolSequences(events) {
    if (events.length < 2) {
        return [];
    }
    // Sort events by timestamp to process chronologically
    const sorted = [...events].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
    const pairCounts = new Map();
    for (let i = 0; i < sorted.length - 1; i++) {
        const curr = sorted[i];
        const next = sorted[i + 1];
        if (curr === undefined || next === undefined) {
            continue;
        }
        const currTime = new Date(curr.timestamp).getTime();
        const nextTime = new Date(next.timestamp).getTime();
        if (nextTime - currTime <= SESSION_GAP_MS) {
            const pairKey = `${curr.toolName}|${next.toolName}`;
            pairCounts.set(pairKey, (pairCounts.get(pairKey) ?? 0) + 1);
        }
    }
    return [...pairCounts.entries()]
        .sort((a, b) => b[1] - a[1])
        .slice(0, 10)
        .map(([key, count]) => {
        const [from, to] = key.split('|');
        return { from, to, count };
    });
}
function formatReport(data) {
    const lines = [
        `# Tool Usage Report — Last ${String(data.days)} days`,
        ``,
        `**Period**: ${data.windowStart.slice(0, 10)} → today | **Total calls**: ${String(data.totalEvents)}`,
        `**Zero-usage tools**: ${String(data.zeroUsageTools.length)} | **Low-usage tools**: ${String(data.lowUsageTools.length)}`,
        ``,
    ];
    // Top tools table
    lines.push(`## Top ${String(Math.min(TOP_TOOLS_LIMIT, data.topTools.length))} Tools`);
    lines.push(``);
    if (data.topTools.length === 0) {
        lines.push(`_No tool calls recorded in this window._`);
    }
    else {
        lines.push(`| Tool | Calls | Trend |`);
        lines.push(`|---|---|---|`);
        for (const t of data.topTools) {
            lines.push(`| ${t.name} | ${String(t.count)} | ${t.trend} |`);
        }
    }
    // Low usage
    lines.push(``);
    lines.push(`## Low-Usage Tools (1–2 calls)`);
    lines.push(``);
    if (data.lowUsageTools.length === 0) {
        lines.push(`_None._`);
    }
    else {
        lines.push(data.lowUsageTools.map((n) => `- ${n}`).join('\n'));
    }
    // Zero usage
    lines.push(``);
    lines.push(`## Zero-Usage Tools (0 calls in window)`);
    lines.push(``);
    if (data.zeroUsageTools.length === 0) {
        lines.push(`_All registered tools were used at least once._`);
    }
    else {
        lines.push(`${String(data.zeroUsageTools.length)} tools never called:`);
        lines.push(``);
        // Show first 30 to stay token-efficient
        const shown = data.zeroUsageTools.slice(0, 30);
        lines.push(shown.map((n) => `- ${n}`).join('\n'));
        if (data.zeroUsageTools.length > 30) {
            lines.push(`- _...and ${String(data.zeroUsageTools.length - 30)} more_`);
        }
    }
    // Sequences
    lines.push(``);
    lines.push(`## Common Tool Sequences (within 60s)`);
    lines.push(``);
    if (data.toolSequences.length === 0) {
        lines.push(`_No sequential patterns detected._`);
    }
    else {
        lines.push(`| From | To | Count |`);
        lines.push(`|---|---|---|`);
        for (const s of data.toolSequences) {
            lines.push(`| ${s.from} | ${s.to} | ${String(s.count)} |`);
        }
    }
    return lines.join('\n');
}
//# sourceMappingURL=tool-usage-report.js.map