/**
 * Usage backfill handler — builds usage reports from stored wake cycle
 * records and uploads them directly to the onboarding server.
 *
 * For legacy rows that lack `tool_calls_json`, the handler attempts to
 * reconstruct tool calls by reading transcript lines from live or archived
 * transcript files (via `readWakeCycleTranscriptLines`).
 *
 * Backfill does NOT enqueue into usage.db and does NOT mutate
 * `usage_reported`. Server-side deduplication by `wakeCycleId` handles
 * any overlap with heartbeat-uploaded reports.
 */
import { OnboardingServiceClient } from "../../onboarding/onboarding-service-client.js";
import { logger } from "../../logger.js";
import { listWakeCyclesForUsageBackfill, readWakeCycleTranscriptLines, extractToolCallsFromLines, updateWakeCycleToolCallsJson, } from "../transcript/transcript-indexer.js";
import { buildWakeCycleUsageReportFromRecord } from "./usage-report-builder.js";
const MAX_BACKFILL_REPORTS = 5_000;
export function createUsageBackfillHandler(config) {
    return async () => {
        if (!config.onboardingServiceUrl || !config.visionclawServiceApiKey) {
            return { status: "failed", result: JSON.stringify({ error: "onboarding service credentials unavailable" }) };
        }
        const rows = listWakeCyclesForUsageBackfill(MAX_BACKFILL_REPORTS);
        const usageReports = [];
        for (const row of rows) {
            let overrideToolCalls;
            // If tool_calls_json is missing, attempt reconstruction from transcripts
            if (!row.tool_calls_json) {
                if (row.source_file && row.end_line > row.start_line) {
                    // Legacy records (pre-0.1.196-beta.2) stored 0-indexed line numbers;
                    // readWakeCycleTranscriptLines expects 1-indexed [startLine, endLine).
                    const isLegacyZeroIndexed = row.start_line === 0;
                    const startLine = isLegacyZeroIndexed ? row.start_line + 1 : row.start_line;
                    const endLine = isLegacyZeroIndexed ? row.end_line + 1 : row.end_line;
                    try {
                        const lines = await readWakeCycleTranscriptLines(row.source_file, startLine, endLine, row.timestamp_start);
                        if (lines.length > 0) {
                            const extracted = extractToolCallsFromLines(lines, {
                                cycleStartedAt: row.timestamp_start,
                                cycleEndedAt: row.timestamp_end,
                            });
                            overrideToolCalls = extracted.toolCalls;
                            // Persist reconstructed tool calls for future backfills
                            try {
                                updateWakeCycleToolCallsJson(row.wake_cycle_id, JSON.stringify(extracted.toolCalls));
                            }
                            catch {
                                // best-effort persistence — non-fatal
                            }
                        }
                    }
                    catch (err) {
                        logger.warn(`[usage-backfill] Could not reconstruct tool calls for ${row.wake_cycle_id}: ${err instanceof Error ? err.message : String(err)}`);
                    }
                }
                // If reconstruction failed or no source file, overrideToolCalls
                // remains undefined and buildWakeCycleUsageReportFromRecord will
                // produce empty tool calls from the NULL tool_calls_json.
            }
            usageReports.push(buildWakeCycleUsageReportFromRecord({
                row,
                config,
                overrideToolCalls,
            }));
        }
        const client = new OnboardingServiceClient(config.onboardingServiceUrl, config.agentName, config.visionclawServiceApiKey);
        const ok = await client.sendUsageBackfill(usageReports);
        if (!ok)
            return { status: "failed", result: JSON.stringify({ error: "backfill upload failed" }) };
        logger.system(`Usage backfill uploaded ${usageReports.length} wake cycle report(s)`);
        return { status: "completed", result: JSON.stringify({ count: usageReports.length }) };
    };
}
//# sourceMappingURL=usage-backfill-handler.js.map