import * as crypto from 'crypto';
import * as path from 'path';
import { Parser, ParsedEvent, inferWorktreeLabel } from './types';
import { estimateCostUsd } from './cost';

/**
 * Claude Code JSONL parser
 *
 * 隐私铁律：只读取 content 块的 `type` 和 `name`，永不读取 input/output。
 * usage / stop_reason / version / cwd / gitBranch 均是 metadata，可上传。
 */
export const claudeParser: Parser = {
  tool: 'claude-code',
  parseLine(line, filePath, pricing): ParsedEvent | null {
    let obj: any;
    try {
      obj = JSON.parse(line);
    } catch {
      return null;
    }
    if (!obj || obj.type !== 'assistant') return null;
    const msg = obj.message;
    if (!msg?.usage) return null;

    const model = msg.model ?? 'unknown';
    const inputTokens = Number(msg.usage.input_tokens ?? 0);
    const outputTokens = Number(msg.usage.output_tokens ?? 0);
    const cacheCreationTokens = Number(msg.usage.cache_creation_input_tokens ?? 0);
    const cacheReadTokens = Number(msg.usage.cache_read_input_tokens ?? 0);

    const sessionId = obj.sessionId ?? path.basename(filePath, '.jsonl');
    const projectPath = obj.cwd ?? deriveProjectPath(filePath);
    const ts = obj.timestamp ?? new Date().toISOString();
    const dedupKey = msg.id ?? crypto.createHash('sha256').update(line).digest('hex').slice(0, 16);
    const rawMessageId = `claude-code:${sessionId}:${dedupKey}`.slice(0, 128);

    const gitBranch =
      typeof obj.gitBranch === 'string' && obj.gitBranch ? obj.gitBranch.slice(0, 255) : undefined;
    const agentVersionEvent =
      typeof obj.version === 'string' && obj.version ? obj.version.slice(0, 32) : undefined;
    const worktreeLabel = inferWorktreeLabel(obj.cwd);
    const cwdBasename = obj.cwd ? path.basename(obj.cwd).slice(0, 255) : undefined;
    const stopReason =
      typeof msg.stop_reason === 'string' ? msg.stop_reason.slice(0, 32) : undefined;
    const serviceTier =
      typeof msg.usage?.service_tier === 'string' ? msg.usage.service_tier.slice(0, 32) : undefined;

    // tool_use 抽取：只读 type + name，绝不碰 input/output
    let toolUseCount = 0;
    const toolNamesSet = new Set<string>();
    if (Array.isArray(msg.content)) {
      for (const c of msg.content) {
        if (c && c.type === 'tool_use' && typeof c.name === 'string') {
          toolUseCount += 1;
          toolNamesSet.add(c.name.slice(0, 64));
        }
      }
    }
    const toolNames = toolNamesSet.size > 0 ? Array.from(toolNamesSet).slice(0, 20) : undefined;

    return {
      rawMessageId,
      tool: 'claude-code',
      sessionId,
      projectPath,
      model,
      ts,
      inputTokens,
      outputTokens,
      cacheCreationTokens,
      cacheReadTokens,
      estimatedCostUsd: estimateCostUsd(model, inputTokens, outputTokens, cacheCreationTokens, cacheReadTokens, pricing),
      gitBranch,
      agentVersionEvent,
      worktreeLabel,
      cwdBasename,
      toolUseCount: toolUseCount > 0 ? toolUseCount : undefined,
      toolNames,
      stopReason,
      serviceTier,
    };
  },
};

function deriveProjectPath(filePath: string): string {
  const dir = path.basename(path.dirname(filePath));
  if (dir.startsWith('-')) return '/' + dir.slice(1).replace(/-/g, '/');
  return dir;
}
