//! Bifrost - The Zenoh-NATS Bridge for MimirsWell.
//!
//! Bridges the real-time Zenoh mesh (Midgard) with the durable NATS backbone (Asgard).

use clap::Parser;
use mimirs_bridge::{bridge_nats_to_zenoh, bridge_zenoh_to_nats};
use std::sync::Arc;
use tracing::{info, warn};

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// Zenoh peer/router addresses
    #[arg(short, long, default_value = "tcp/127.0.0.1:7447")]
    zenoh_peer: String,

    /// NATS server address
    #[arg(short, long, default_value = "nats://127.0.0.1:4222")]
    nats_server: String,

    /// Zenoh key prefix to bridge to NATS
    #[arg(long, default_value = "mimirs/signal/**")]
    zenoh_to_nats_prefix: String,

    /// NATS subject to bridge to Zenoh
    #[arg(long, default_value = "MIMIRS.SIGNAL.>")]
    nats_to_zenoh_subject: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    tracing_subscriber::fmt::init();
    let args = Args::parse();

    info!("Initializing Bifrost Bridge (Zenoh 1.9.0 + NATS 0.48)...");

    // 1. Initialize Zenoh session
    let config_str = if !args.zenoh_peer.is_empty() {
        format!(
            r#"{{"mode": "client", "connect": {{"endpoints": ["{}"]}}}}"#,
            args.zenoh_peer
        )
    } else {
        r#"{"mode": "client"}"#.to_string()
    };

    let config = zenoh::Config::from_json5(&config_str)
        .map_err(|e| format!("Invalid Zenoh config: {}", e))?;
    let zenoh_session = Arc::new(
        zenoh::open(config)
            .await
            .map_err(|e| format!("Zenoh open error: {}", e))?,
    );
    info!("Connected to Zenoh: {}", args.zenoh_peer);

    // 2. Initialize NATS connection
    let nats_client = Arc::new(async_nats::connect(&args.nats_server).await?);
    info!("Connected to NATS: {}", args.nats_server);

    // 3. Bridge: Zenoh -> NATS
    let zenoh_handle = tokio::spawn(bridge_zenoh_to_nats(
        zenoh_session.clone(),
        nats_client.clone(),
        args.zenoh_to_nats_prefix,
    ));

    // 4. Bridge: NATS -> Zenoh
    let nats_handle = tokio::spawn(bridge_nats_to_zenoh(
        zenoh_session.clone(),
        nats_client.clone(),
        args.nats_to_zenoh_subject,
    ));

    // Handle signals for graceful shutdown
    tokio::select! {
        _ = tokio::signal::ctrl_c() => info!("Shutdown signal received"),
        res = zenoh_handle => warn!("Zenoh bridge task finished: {:?}", res),
        res = nats_handle => warn!("NATS bridge task finished: {:?}", res),
    }

    info!("Bifrost Bridge shutting down...");
    Ok(())
}
