#[cfg(feature = "cli")]
use clap::Parser;

#[cfg(feature = "cli")]
#[derive(Debug, Parser)]
#[command(
    name = "mijia-spec",
    version,
    about = "Fetch Xiaomi MIoT v2 device specs by URN"
)]
struct Cli {
    /// Device URN, for example: urn:miot-spec-v2:device:router:0000A031:xiaomi-rd08:1
    #[arg(short = 'u', long, value_name = "URN")]
    urn: String,

    /// Optional disk cache directory when fetching by URN.
    #[arg(long, value_name = "DIR")]
    cache_dir: Option<std::path::PathBuf>,

    /// Pretty-print JSON output.
    #[arg(long)]
    pretty: bool,
}

#[cfg(feature = "cli")]
fn main() {
    if let Err(err) = run() {
        eprintln!("error: {err}");
        std::process::exit(1);
    }
}

#[cfg(feature = "cli")]
fn run() -> Result<(), Box<dyn std::error::Error>> {
    let cli = Cli::parse();

    let mut client = mijia_spec::MijiaSpecClient::new();
    if let Some(dir) = cli.cache_dir {
        client = client.with_disk_cache(dir)?;
    }
    let spec = client.get(&cli.urn)?;

    #[derive(serde::Serialize)]
    struct CliOutput<'a> {
        instance: &'a mijia_spec::miot_spec_v2::DeviceInstance,
        #[serde(skip_serializing_if = "Option::is_none")]
        translation: Option<&'a mijia_spec::miot_spec_v2::Translation>,
    }

    let payload = CliOutput {
        instance: spec.instance(),
        translation: spec.translation(),
    };

    let output = if cli.pretty {
        serde_json::to_string_pretty(&payload)?
    } else {
        serde_json::to_string(&payload)?
    };
    println!("{output}");

    Ok(())
}

#[cfg(not(feature = "cli"))]
fn main() {
    eprintln!("CLI is disabled. Rebuild with `--features cli`.");
    std::process::exit(1);
}
