use std::{process::ExitCode, sync::Arc, time::Duration};

use tici_service_discovery::{
    EtcdClient, EtcdDiscoveryClient, META_SERVICE_REGISTER_KEY_PREFIX,
    discovery::client::DiscoveryClient,
};

fn usage() -> ExitCode {
    eprintln!("Usage: meta_discovery_probe --pd-addr <addr[,addr2,...]>");
    ExitCode::FAILURE
}

fn parse_pd_addr() -> Option<String> {
    let mut args = std::env::args().skip(1);
    while let Some(arg) = args.next() {
        if arg == "--pd-addr" {
            return args.next();
        }
    }
    None
}

fn normalize_pd_addrs(pd_addr: &str) -> Vec<String> {
    pd_addr
        .split(',')
        .filter_map(|addr| {
            let trimmed = addr.trim();
            if trimmed.is_empty() {
                None
            } else if trimmed.starts_with("http://") || trimmed.starts_with("https://") {
                Some(trimmed.to_string())
            } else {
                Some(format!("http://{}", trimmed))
            }
        })
        .collect()
}

#[tokio::main(flavor = "current_thread")]
async fn main() -> ExitCode {
    let Some(pd_addr) = parse_pd_addr() else {
        return usage();
    };

    let endpoints = normalize_pd_addrs(&pd_addr);
    if endpoints.is_empty() {
        return usage();
    }

    let observer = EtcdDiscoveryClient::new(
        META_SERVICE_REGISTER_KEY_PREFIX,
        Arc::new(EtcdClient::new_for_test(endpoints)),
        Duration::from_secs(10),
        Duration::from_secs(3),
    );

    match observer.get_all_peers().await {
        Ok(mut peers) => {
            peers.nodes.sort();
            println!("leader={}", peers.leader.unwrap_or_default());
            for peer in peers.nodes {
                println!("peer={peer}");
            }
            ExitCode::SUCCESS
        }
        Err(err) => {
            eprintln!("probe failed: {err}");
            ExitCode::FAILURE
        }
    }
}
