//! Code System Kubernetes Operator
//!
//! Manages the lifecycle of: App, GitServer, EmailWorker, GitHook, Migrate CRDs.

use operator::context::ReconcileCtx;
use std::sync::Arc;
use tracing::{Level, error, info};
use tracing_subscriber::FmtSubscriber;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // ---- Logging ----
    let log_level = std::env::var("OPERATOR_LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
    let level = match log_level.to_lowercase().as_str() {
        "trace" => Level::TRACE,
        "debug" => Level::DEBUG,
        "info" => Level::INFO,
        "warn" => Level::WARN,
        "error" => Level::ERROR,
        _ => Level::INFO,
    };
    FmtSubscriber::builder()
        .with_max_level(level)
        .with_target(false)
        .with_thread_ids(false)
        .with_file(true)
        .with_line_number(true)
        .compact()
        .init();

    let ctx = Arc::new(ReconcileCtx::from_env().await?);
    info!(
        namespace = ctx.operator_namespace,
        image_prefix = ctx.image_prefix,
        "code-operator starting"
    );

    // ---- Spawn all 5 controllers ----
    let app_handle = tokio::spawn({
        let ctx = ctx.clone();
        let client = ctx.client.clone();
        async move {
            use operator::controller;
            if let Err(e) = controller::start_app(client, ctx).await {
                error!(%e, "app controller stopped");
            }
        }
    });

    let gs_handle = tokio::spawn({
        let ctx = ctx.clone();
        let client = ctx.client.clone();
        async move {
            use operator::controller;
            if let Err(e) = controller::start_gitserver(client, ctx).await {
                error!(%e, "gitserver controller stopped");
            }
        }
    });

    let ew_handle = tokio::spawn({
        let ctx = ctx.clone();
        let client = ctx.client.clone();
        async move {
            use operator::controller;
            if let Err(e) = controller::start_email_worker(client, ctx).await {
                error!(%e, "email_worker controller stopped");
            }
        }
    });

    let gh_handle = tokio::spawn({
        let ctx = ctx.clone();
        let client = ctx.client.clone();
        async move {
            use operator::controller;
            if let Err(e) = controller::start_git_hook(client, ctx).await {
                error!(%e, "git_hook controller stopped");
            }
        }
    });

    let mig_handle = tokio::spawn({
        let ctx = ctx.clone();
        let client = ctx.client.clone();
        async move {
            use operator::controller;
            if let Err(e) = controller::start_migrate(client, ctx).await {
                error!(%e, "migrate controller stopped");
            }
        }
    });

    // ---- Graceful shutdown on SIGINT / SIGTERM ----
    tokio::signal::ctrl_c().await.ok();

    info!("code-operator stopped");
    let _ = tokio::join!(app_handle, gs_handle, ew_handle, gh_handle, mig_handle,);
    Ok(())
}
