#![forbid(unsafe_code)]

//! provctl - Lightweight service control CLI
//!
//! A kubectl-style CLI for managing services across different backends
//! (systemd, launchd, pidfile).

use clap::{Parser, Subcommand};
use provctl_backend::{Backend, PidfileBackend};
use provctl_core::{ServiceDefinition, ServiceName};
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[command(name = "provctl")]
#[command(about = "Lightweight service control CLI", long_about = None)]
#[command(version = "0.1.0")]
#[command(author = "Syntaxis Contributors")]
struct Cli {
    /// Configuration directory (default: ~/.config/provctl)
    #[arg(short, long)]
    config_dir: Option<PathBuf>,

    /// Verbosity level (0=quiet, 1=normal, 2=verbose, 3=debug)
    #[arg(short, long, default_value = "1")]
    verbosity: u8,

    #[command(subcommand)]
    command: Option<Commands>,
}

#[derive(Subcommand, Debug)]
enum Commands {
    /// Start a service
    Start {
        /// Service name to start
        service: String,

        /// Path to binary (if not in config)
        #[arg(short, long)]
        binary: Option<PathBuf>,

        /// Service arguments
        #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
        args: Vec<String>,
    },

    /// Stop a service
    Stop {
        /// Service name to stop
        service: String,
    },

    /// Restart a service
    Restart {
        /// Service name to restart
        service: String,
    },

    /// Show service status
    Status {
        /// Service name
        service: String,
    },

    /// Show service logs
    Logs {
        /// Service name
        service: String,

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

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

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

    // Initialize logging based on verbosity
    let log_level = match cli.verbosity {
        0 => log::LevelFilter::Error,
        1 => log::LevelFilter::Info,
        2 => log::LevelFilter::Debug,
        3 => log::LevelFilter::Trace,
        _ => log::LevelFilter::Info,
    };

    env_logger::Builder::from_default_env()
        .filter_level(log_level)
        .init();

    // Get configuration directory
    let config_dir = cli.config_dir.unwrap_or_else(|| {
        let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
        PathBuf::from(home).join(".config/provctl")
    });

    log::debug!("Using config directory: {:?}", config_dir);

    // Create backend (using pidfile as default for now)
    let pid_dir = PathBuf::from("/tmp");
    let backend = PidfileBackend::new(&pid_dir);

    // Execute command
    match cli.command {
        Some(Commands::Start {
            service,
            binary,
            args,
        }) => {
            let name = ServiceName::new(&service)?;
            let bin = binary.unwrap_or_else(|| PathBuf::from(&service));

            let service_def = ServiceDefinition::new(name, bin).with_args(args);

            match backend.start(&service_def).await {
                Ok(pid) => {
                    println!("✅ Started {} (PID: {})", service, pid);
                }
                Err(e) => {
                    eprintln!("❌ Failed to start {}: {}", service, e);
                    return Err(e.into());
                }
            }
        }

        Some(Commands::Stop { service }) => match backend.stop(&service).await {
            Ok(()) => {
                println!("✅ Stopped {}", service);
            }
            Err(e) => {
                eprintln!("❌ Failed to stop {}: {}", service, e);
                return Err(e.into());
            }
        },

        Some(Commands::Restart { service }) => {
            let name = ServiceName::new(&service)?;
            let service_def = ServiceDefinition::new(name, PathBuf::from(&service));

            match backend.restart(&service_def).await {
                Ok(pid) => {
                    println!("✅ Restarted {} (PID: {})", service, pid);
                }
                Err(e) => {
                    eprintln!("❌ Failed to restart {}: {}", service, e);
                    return Err(e.into());
                }
            }
        }

        Some(Commands::Status { service }) => match backend.status(&service).await {
            Ok(status) => {
                println!("Service {}: {}", service, status);
            }
            Err(e) => {
                eprintln!("❌ Failed to get status: {}", e);
                return Err(e.into());
            }
        },

        Some(Commands::Logs { service, lines, .. }) => match backend.logs(&service, lines).await {
            Ok(log_lines) => {
                for line in log_lines {
                    println!("{}", line);
                }
            }
            Err(e) => {
                eprintln!("❌ Failed to get logs: {}", e);
                return Err(e.into());
            }
        },

        None => {
            println!("provctl - Lightweight service control CLI");
            println!("Version: 0.1.0");
            println!("\nUse 'provctl --help' for more information");
        }
    }

    Ok(())
}
