use clap::Parser;
use serde_json::Value;
use tokio_postgres::NoTls;

mod queries;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    #[arg(short, long)]
    database: String, // PostgreSQL URL
    #[arg(short, long)]
    query: String, // Optional key to filter by
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let args = Args::parse();

    // Connect to PostgreSQL
    let (client, connection) = tokio_postgres::connect(&args.database, NoTls).await?;
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("Connection error: {}", e);
        }
    });

    let query: queries::Query = serde_saphyr::from_str(&std::fs::read_to_string(&args.query)?)?;

    if let Some(fetch_all) = query.fetch_all {
        // Dump all rows with the specified key
        let rows = client
            .query(
                "SELECT id, data FROM measurements WHERE key = $1",
                &[&fetch_all.key],
            )
            .await?;
        for row in rows {
            let id: uuid::Uuid = row.try_get(0)?;
            let data: Value = row.try_get(1)?;
            println!("ID: {}, Data: {}", id, serde_json::to_string_pretty(&data)?);
        }
    }
    if query.all_keys.is_some() {
        // List unique keys from the measurements table, sorted
        println!("List of unique keys (sorted):\n");
        let rows = client
            .query("SELECT DISTINCT key FROM measurements ORDER BY key", &[])
            .await?;
        for row in rows {
            let key: String = row.try_get(0)?;
            println!("- {}", key);
        }
    }

    Ok(())
}
