use anyhow::Result;
use clap::Parser;
use ethl::storage::store::{EventStore, directory::IntegrityStatus};
use tracing::info;

use crate::commands::full_signatures_to_events;

#[derive(Parser, Debug)]
pub struct RepairArgs {
    /// Full event signatures to filter and parse against (e.g. "event Transfer(address from,address to,uint256 amount)")
    #[arg(long, required = true)]
    events: Vec<String>,

    /// The archived events location (eg: file:///tmp/events or s3://my-bucket/events)
    #[arg(long, required = true)]
    archive_path: String,

    /// Dry run - show what would be repaired and which errors
    #[arg(long, default_value_t = false)]
    dry_run: bool,
}

pub async fn run_repair_command(args: RepairArgs) -> Result<()> {
    let events = full_signatures_to_events(&args.events)?;

    for event in &events {
        let store = EventStore::from_uri(&args.archive_path, &event.try_into()?)?;
        let integrity = store.list().await?.integrity_report();

        match integrity.status() {
            IntegrityStatus::Intact => {
                info!("Event {}: Archive is valid, no repairs needed", &event.name);
                continue;
            }
            IntegrityStatus::Unrepairable => {
                info!(
                    "Event {}: Archive is unrepairable: {}",
                    &event.name, integrity
                );
                continue;
            }
            IntegrityStatus::Repairable => {
                info!(
                    "Event {}: Archive has integrity issues, attempting repair: {}",
                    &event.name, integrity
                );

                if !args.dry_run {
                    store.repair().await?;
                }
            }
        }
    }

    Ok(())
}
