'use strict';

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

class WalleJsonlAdapter extends SourceAdapterBase {
  static schema = {
    adapterId: 'walle-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('walle', 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 = [];

    for (const { line, event } of events) {
      if (event.type === 'session_meta' || event.type === 'session_start') {
        cwd = event.cwd || event.data?.cwd || cwd;
        gitBranch = event.gitBranch || gitBranch;
        continue;
      }
      if (event.type === 'user' || event.type === 'assistant') {
        const role = event.type;
        const content = role === 'user'
          ? cleanUserText(extractMessageText(event.message || event))
          : extractMessageText(event.message || event);
        if (!content || looksLikeToolResult(content)) continue;
        const message = {
          itemId: event.uuid || `line-${line}`,
          role,
          content,
          timestamp: toIso(event.timestamp),
          cwd: event.cwd || cwd,
          gitBranch: event.gitBranch || gitBranch,
          rawType: event.type,
          harness: 'walle',
          toolCalls: [],
        };
        messages.push(message);
        for (const record of messageToRecords({ source, message, version })) yield record;
        continue;
      }
      if (event.type === 'walle_part' && (event.partType === 'tool_call' || event.partType === 'tool')) {
        const data = event.data || {};
        const name = data.name || data.tool || 'tool';
        const itemId = event.uuid || `tool-${line}`;
        yield sourceItem({
          source,
          itemId,
          version,
          timestamp: event.timestamp,
          metadata: { role: 'tool', cwd, gitBranch, name, input: data.input || {} },
        });
        yield memoryRecord({
          source,
          itemId: `${itemId}:tool`,
          memoryType: 'coding_session_tool_call',
          role: 'tool',
          contentRaw: `[Tool: ${name}] ${summarizeToolInput(name, data.input || {})}`,
          timestamp: event.timestamp,
          metadata: { cwd, gitBranch, name, input: data.input || {} },
        });
      }
    }

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

module.exports = WalleJsonlAdapter;
