use rusqlite::Connection;

use crate::db::Event;

pub fn export_json(conn: &Connection) -> Result<(), Box<dyn std::error::Error>> {
    let mut stmt = conn.prepare(
        "SELECT ts, pwd, cmd, exit_code, duration FROM events ORDER BY ts ASC",
    )?;
    let events: Vec<Event> = stmt
        .query_map([], |row| {
            Ok(Event {
                ts: row.get(0)?,
                pwd: row.get(1)?,
                cmd: row.get(2)?,
                exit_code: row.get(3)?,
                duration: row.get(4)?,
            })
        })?
        .flatten()
        .collect();

    print!("[");
    for (i, e) in events.iter().enumerate() {
        if i > 0 {
            print!(",");
        }
        println!();
        println!("  {{");
        println!("    \"ts\": {},", e.ts);
        println!("    \"pwd\": \"{}\",", e.pwd.replace('"', "\\\""));
        println!("    \"cmd\": \"{}\",", e.cmd.replace('\\', "\\\\").replace('"', "\\\""));
        println!("    \"exit_code\": {},", e.exit_code);
        println!("    \"duration\": {}", e.duration);
        print!("  }}");
    }
    if !events.is_empty() {
        println!();
    }
    println!("]");
    Ok(())
}

pub fn export_csv(conn: &Connection) -> Result<(), Box<dyn std::error::Error>> {
    let mut stmt = conn.prepare(
        "SELECT ts, pwd, cmd, exit_code, duration FROM events ORDER BY ts ASC",
    )?;
    let events: Vec<Event> = stmt
        .query_map([], |row| {
            Ok(Event {
                ts: row.get(0)?,
                pwd: row.get(1)?,
                cmd: row.get(2)?,
                exit_code: row.get(3)?,
                duration: row.get(4)?,
            })
        })?
        .flatten()
        .collect();

    println!("ts,pwd,cmd,exit_code,duration");
    for e in &events {
        let cmd_escaped = e.cmd.replace('"', "\"\"");
        let pwd_escaped = e.pwd.replace('"', "\"\"");
        println!(
            "{},\"{}\",\"{}\",{},{}",
            e.ts, pwd_escaped, cmd_escaped, e.exit_code, e.duration
        );
    }
    Ok(())
}
