//! Row parsing helpers for converting SQLite rows to domain types.

use fyi_core::{Event, EventType, parse_timestamp_millis};

/// Convert a SQLite row to an Event.
///
/// Expected column order:
/// 0: id, 1: machine_id, 2: timestamp, 3: event_type, 4: session_id,
/// 5: framework, 6: tool_use_id, 7: spawned_agent_id, 8: tool_name,
/// 9: subagent_type, 10: permission_mode, 11: transcript_path,
/// 12: pid, 13: cwd, 14: model, 15: tokens_input, 16: tokens_output,
/// 17: tokens_cache_read, 18: tokens_cache_creation, 19: cost_usd,
/// 20: duration_ms, 21: payload, 22: metadata
pub(crate) fn row_to_event(row: &rusqlite::Row<'_>) -> rusqlite::Result<Event> {
    let ts_millis: i64 = row.get(2)?;
    let timestamp = parse_timestamp_millis(ts_millis).ok_or_else(|| {
        rusqlite::Error::InvalidColumnType(
            2,
            "timestamp".to_string(),
            rusqlite::types::Type::Integer,
        )
    })?;

    let event_type_str: String = row.get(3)?;
    // FromStr for EventType is infallible, so unwrap is safe
    let event_type: EventType = event_type_str.parse().unwrap();

    Ok(Event {
        id: Some(row.get(0)?),
        machine_id: row.get(1)?,
        timestamp,
        event_type,
        session_id: row.get(4)?,
        framework: row.get(5)?,
        tool_use_id: row.get(6)?,
        spawned_agent_id: row.get(7)?,
        tool_name: row.get(8)?,
        subagent_type: row.get(9)?,
        permission_mode: row.get(10)?,
        transcript_path: row.get(11)?,
        pid: row.get(12)?,
        cwd: row.get(13)?,
        model: row.get(14)?,
        tokens_input: row.get(15)?,
        tokens_output: row.get(16)?,
        tokens_cache_read: row.get(17)?,
        tokens_cache_creation: row.get(18)?,
        cost_usd: row.get(19)?,
        duration_ms: row.get(20)?,
        payload: row.get(21)?,
        metadata: row.get(22)?,
    })
}
