//! Kegani CLI — A developer-friendly Rust web framework
//!
//! Usage:
//!   keg init <name>           Create a new project
//!   keg gen <kind> <name>     Generate code
//!   keg run [--watch]         Run with hot reload
//!   keg build [--target TRI]  Build release binary
//!   keg docker                Generate Dockerfile + compose
//!   keg env                   Show environment info
//!   keg up                    Update Kegani
//!   keg migrate <action>      Run migrations
//!   keg clean                 Clean build artifacts

mod commands;
mod types;

use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};

use commands::{gen::GenKind, MigrateAction};

/// Kegani CLI — Build production-ready Rust web apps with a single binary
#[derive(Parser)]
#[command(
    name = "keg",
    version,
    author = "Your Name <you@example.com>",
    about = "Kegani: a developer-friendly, ergonomic, production-ready Rust web framework",
    long_about = "Kegani — A complete Rust web framework in a single binary

Commands:
  init        Create a complete project with layered architecture
  gen         Generate code: api, model, service, repository, controller, middleware, migration
  run         Run the application with hot reload (file watching)
  build       Build a release binary (cross-compile supported)
  docker      Generate Dockerfile and docker-compose.yml
  env         Print environment diagnostics
  up          Update Kegani framework and CLI
  migrate     Run database migrations (up, down, status, reset)
  clean       Remove build artifacts

Examples:
  keg init my-api                        Create a new project
  keg gen api article                     Generate full CRUD stack
  keg gen model user                      Generate entity
  keg gen migration create_users          Generate SQL migration
  keg run                                Run with hot reload
  keg docker                             Generate Docker files
  keg build --target x86_64-unknown-linux-musl"
)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Create a complete new project with layered architecture
    Init {
        /// Project name (creates a directory with this name)
        name: String,

        /// Project template (default: api)
        #[arg(short, long, default_value = "api")]
        template: String,
    },
    /// Generate code (controller, model, service, repository, middleware, migration, or full api)
    Gen {
        /// What to generate
        #[arg(value_enum)]
        kind: GenKind,

        /// Name of the resource to generate
        name: String,
    },
    /// Run the application with optional hot reload
    Run {
        /// Port to listen on
        #[arg(short, long, default_value = "8080")]
        port: u16,

        /// Enable hot reload (watch .rs files for changes)
        #[arg(short, long, default_value = "true")]
        watch: bool,
    },
    /// Build a release binary
    Build {
        /// Target triple for cross-compilation (e.g., x86_64-unknown-linux-musl)
        #[arg(short, long)]
        target: Option<String>,
    },
    /// Generate Dockerfile and docker-compose.yml
    Docker,
    /// Print environment information and diagnostics
    Env,
    /// Update Kegani framework to the latest version
    Up,
    /// Run database migrations
    Migrate {
        /// Migration action
        #[arg(value_enum)]
        action: MigrateAction,
    },
    /// Clean build artifacts
    Clean {
        /// Remove all build artifacts and cache
        #[arg(short, long, default_value = "false")]
        all: bool,
    },
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    match cli.command {
        Commands::Init { name, template } => commands::init::init(&name, &template)?,
        Commands::Gen { kind, name } => commands::gen::gen(kind, &name)?,
        Commands::Run { port, watch } => commands::run::run(port, watch)?,
        Commands::Build { target } => commands::build::build(target.as_deref())?,
        Commands::Docker => commands::docker::docker()?,
        Commands::Env => commands::env::env()?,
        Commands::Up => commands::update::update()?,
        Commands::Migrate { action } => commands::migrate::run_migration(action)?,
        Commands::Clean { all } => commands::clean::clean(all)?,
    }

    Ok(())
}