//! SEA-Forge CLI - The Organization Compiler
//!
//! A command-line interface for managing SEA-Forge development environments,
//! services, and validation workflows.

mod commands;
mod config;
mod doctor;
mod services;
mod state;

use clap::{Parser, Subcommand};
use colored::Colorize;
use std::process::ExitCode;

/// SEA-Forge CLI - The Organization Compiler
#[derive(Parser)]
#[command(name = "sea-forge")]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
    #[command(subcommand)]
    command: Commands,

    /// Enable verbose output
    #[arg(short, long, global = true)]
    verbose: bool,

    /// Dry run mode - show what would be done without making changes
    #[arg(long, global = true)]
    dry_run: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Check system prerequisites and environment health
    Doctor,

    /// Initialize a new SEA-Forge project (or refresh existing)
    Init {
        /// Skip interactive prompts
        #[arg(long)]
        yes: bool,
    },

    /// Start all services (LibreChat, Oxigraph, etc.)
    Up {
        /// Start only specific service(s)
        #[arg(short, long)]
        service: Option<Vec<String>>,

        /// Detach and run in background
        #[arg(short, long, default_value = "true")]
        detach: bool,

        /// Watch mode: restart unhealthy services
        #[arg(short, long)]
        watch: bool,
    },

    /// Stop all services
    Down {
        /// Remove volumes (destructive)
        #[arg(short, long)]
        volumes: bool,
    },

    /// Run spec validation (spec-guard)
    Validate {
        /// Specific spec file to validate
        #[arg(short, long)]
        file: Option<String>,
    },

    /// Interactive setup for LibreChat + Zed IDE
    Setup {
        /// Skip Zed IDE configuration
        #[arg(long)]
        skip_zed: bool,

        /// Skip LibreChat configuration
        #[arg(long)]
        skip_librechat: bool,
    },

    /// Check service status
    Status,

    /// View service logs
    Logs {
        /// Service name (default: all)
        service: Option<String>,

        /// Number of lines to show
        #[arg(short = 'n', long, default_value = "50")]
        lines: u32,

        /// Follow log output
        #[arg(short, long)]
        follow: bool,
    },

    /// Apply declared state from sea-forge.yaml
    Apply {
        /// Force apply even if fingerprints match
        #[arg(short, long)]
        force: bool,
    },

    /// Watch and auto-heal unhealthy services
    Watch {
        /// Health check interval in seconds
        #[arg(short, long, default_value = "30")]
        interval: u64,
    },
}

#[tokio::main]
async fn main() -> ExitCode {
    let cli = Cli::parse();

    // Initialize tracing
    if cli.verbose {
        tracing_subscriber::fmt()
            .with_env_filter("sea_forge=debug")
            .init();
    }

    // Print banner
    print_banner();

    let result = match cli.command {
        Commands::Doctor => commands::doctor::run(cli.verbose).await,
        Commands::Init { yes } => commands::init::run(yes, cli.dry_run).await,
        Commands::Up {
            service,
            detach,
            watch,
        } => {
            let res = commands::up::run(service, detach, cli.dry_run).await;
            if res.is_ok() && watch {
                // Enter watch mode after starting
                commands::watch::run(30).await
            } else {
                res
            }
        }
        Commands::Down { volumes } => commands::down::run(volumes, cli.dry_run).await,
        Commands::Validate { file } => commands::validate::run(file).await,
        Commands::Setup {
            skip_zed,
            skip_librechat,
        } => commands::setup::run(skip_zed, skip_librechat, cli.dry_run).await,
        Commands::Status => commands::status::run().await,
        Commands::Logs {
            service,
            lines,
            follow,
        } => commands::logs::run(service, lines, follow).await,
        Commands::Apply { force } => commands::apply::run(cli.dry_run, force).await,
        Commands::Watch { interval } => commands::watch::run(interval).await,
    };

    match result {
        Ok(()) => ExitCode::SUCCESS,
        Err(e) => {
            eprintln!("{} {}", "error:".red().bold(), e);
            ExitCode::FAILURE
        }
    }
}

fn print_banner() {
    println!(
        "{}",
        r#"
  ╔═══════════════════════════════════════╗
  ║   🌊 SEA-Forge CLI                    ║
  ║   The Organization Compiler           ║
  ╚═══════════════════════════════════════╝
"#
        .cyan()
    );
}
