use anyhow::Result;
#[cfg(not(test))]
use lesavka_client::{LesavkaClientApp, launcher};
use std::{env, fs::OpenOptions, path::Path};
use tracing_appender::non_blocking;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{filter::EnvFilter, fmt, prelude::*};
fn ensure_runtime_dir() {
    if env::var_os("XDG_RUNTIME_DIR").is_none() {
        let msg = "Error: $XDG_RUNTIME_DIR is not set. \
                   Launch the client from a regular desktop session or export it manually, \
                   e.g. `export XDG_RUNTIME_DIR=/run/user/$(id -u)`.";
        #[cfg(test)]
        panic!("{msg}");
        #[cfg(not(test))]
        {
            eprintln!("{msg}");
            std::process::exit(1);
        }
    }
}
#[forbid(unsafe_code)]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
    #[cfg(not(test))]
    let args = env::args().skip(1).collect::<Vec<_>>();

    #[cfg(not(test))]
    if args.iter().any(|arg| arg == "--version" || arg == "-V") {
        println!("lesavka-client {}", lesavka_client::VERSION);
        return Ok(());
    }

    let headless = env::var("LESAVKA_HEADLESS").is_ok();
    if !headless {
        ensure_runtime_dir();
    }
    let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
        EnvFilter::new(
            "warn,\
             lesavka_client::app=info,\
             lesavka_client::input::camera=debug,\
             lesavka_client::output::video=info,\
             lesavka_client::output::audio=info,\
             tonic=warn,\
             h2=warn,\
             tower=warn",
        )
    });
    let stderr_layer = fmt::layer()
        .with_target(true)
        .with_thread_ids(true)
        .with_file(true);
    let dev_mode = env::var("LESAVKA_DEV_MODE").is_ok();
    let mut _guard: Option<WorkerGuard> = None;
    if dev_mode {
        let log_path = Path::new("/tmp").join("lesavka-client.log");
        let file = OpenOptions::new()
            .create(true)
            .write(true)
            .truncate(true)
            .open(&log_path)?;
        let (file_writer, guard) = non_blocking(file);
        _guard = Some(guard);
        let file_layer = fmt::layer()
            .with_writer(file_writer)
            .with_ansi(false)
            .with_target(true)
            .with_level(true);
        tracing_subscriber::registry()
            .with(env_filter)
            .with(stderr_layer)
            .with(file_layer)
            .try_init()
            .ok();
        tracing::info!(
            "📜 lesavka-client running in DEV mode → {}",
            log_path.display()
        );
    } else {
        tracing_subscriber::registry()
            .with(env_filter)
            .with(stderr_layer)
            .try_init()
            .ok();
    }
    #[cfg(test)]
    {
        if env::var("LESAVKA_TEST_SKIP_APP").is_ok() {
            return Ok(());
        }
        Ok(())
    }
    #[cfg(not(test))]
    {
        if env::var("LESAVKA_LAUNCHER_CHILD").is_ok() {
            launcher::start_launcher_child_parent_watchdog_from_env();
        }

        if env::var("LESAVKA_LAUNCHER_CHILD").is_err() && launcher::maybe_run_launcher(&args)? {
            return Ok(());
        }

        let mut app = LesavkaClientApp::new()?;
        app.run().await
    }
}
