'use strict';

const { SourceAdapterBase } = require('./base');
const {
  cleanUserText,
  extractMessageText,
  fileVersion,
  looksLikeToolResult,
  parseToolInput,
  readJsonlFile,
  sourceIdFromFile,
  summarizeToolInput,
  toIso,
} = require('./jsonl-utils');
const { buildExchangeRecords, memoryRecord, messageToRecords, sourceItem } = require('./coding-session-utils');

class CodexJsonlAdapter extends SourceAdapterBase {
  static schema = {
    adapterId: 'codex-jsonl',
    version: '1.0.0',
    supportsIncremental: true,
    defaultPrivacyClass: 'pii_potential',
    declaredTransformations: [
      'newline_normalize',
      'strip_tool_chrome',
      'base64_payload_omit',
      'tool_result_summarize',
      'whitespace_trim',
      'exchange_pair_chunk',
    ],
    fields: {
      sourceId: { type: 'string', required: true },
      sourceFile: { type: 'string', required: true },
      cwd: { type: 'string', required: false },
      gitBranch: { type: 'string', required: false },
    },
  };

  validateSource(source) {
    const normalized = super.validateSource(source);
    if (!source.sourceId) normalized.sourceId = sourceIdFromFile('codex', normalized.sourceFile || normalized.uri);
    return normalized;
  }

  async *ingest({ source, context }) {
    const filePath = source.sourceFile || source.uri;
    const version = fileVersion(filePath);
    const { events, diagnostics } = readJsonlFile(filePath);
    for (const diagnostic of diagnostics) context?.warn?.(diagnostic.message, diagnostic);

    let cwd = source.cwd || '';
    let gitBranch = source.metadata?.gitBranch || '';
    const messages = [];
    const seen = new Set();

    for (const { line, event } of events) {
      const payload = event.payload || {};
      const item = payload.item || payload;
      if (event.type === 'session_meta') {
        cwd = payload.cwd || cwd;
        gitBranch = payload.gitBranch || gitBranch;
        continue;
      }
      if (event.type === 'turn_context') {
        cwd = payload.cwd || cwd;
        gitBranch = payload.gitBranch || gitBranch;
        continue;
      }

      if (event.type !== 'response_item' && event.type !== 'event_msg') continue;

      const role = item.role || payload.role || event.role || null;
      if (role === 'user' || role === 'assistant') {
        const content = role === 'user'
          ? cleanUserText(extractMessageText(item))
          : extractMessageText(item);
        if (!content || looksLikeToolResult(content)) continue;
        const itemId = item.id || payload.id || `${event.type}-${line}`;
        const key = `${role}:${itemId}:${content}`;
        if (seen.has(key)) continue;
        seen.add(key);
        const message = {
          itemId,
          role,
          content,
          timestamp: toIso(event.timestamp || payload.timestamp || item.timestamp),
          cwd,
          gitBranch,
          rawType: event.type,
          harness: 'codex',
          toolCalls: [],
        };
        messages.push(message);
        for (const record of messageToRecords({ source, message, version })) yield record;
        continue;
      }

      if (payload.type === 'function_call' || item.type === 'function_call') {
        const name = item.name || payload.name || 'tool';
        const input = parseToolInput(item.arguments ?? payload.arguments ?? item.input ?? payload.input);
        const itemId = item.id || payload.id || `tool-${line}`;
        yield sourceItem({
          source,
          itemId,
          version,
          timestamp: event.timestamp || payload.timestamp,
          metadata: { role: 'tool', cwd, gitBranch, name, input },
        });
        yield memoryRecord({
          source,
          itemId: `${itemId}:tool`,
          memoryType: 'coding_session_tool_call',
          role: 'tool',
          contentRaw: `[Tool: ${name}] ${summarizeToolInput(name, input)}`,
          timestamp: event.timestamp || payload.timestamp,
          metadata: { cwd, gitBranch, name, input },
        });
      }
    }

    for (const record of buildExchangeRecords(source, messages)) yield record;
  }
}

module.exports = CodexJsonlAdapter;
