use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
#[command(name = "fyi")]
#[command(about = "AI coding assistant hook event logger", long_about = None)]
#[command(version)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Subcommand, Debug)]
pub enum Commands {
    /// Activate fyi for AI coding frameworks
    Activate {
        /// Frameworks to activate (claude, gemini, codex). If omitted, auto-detects installed frameworks.
        #[arg(value_name = "FRAMEWORKS")]
        frameworks: Vec<String>,

        /// Install hooks to project config instead of global
        #[arg(long, conflicts_with = "settings_local")]
        local: bool,

        /// Install hooks to project local config (not committed to git)
        #[arg(long, conflicts_with = "local")]
        settings_local: bool,

        /// Print hooks JSON to stdout instead of writing to file
        #[arg(long)]
        print: bool,

        /// Only initialize database, skip hook installation
        #[arg(long)]
        db_only: bool,

        /// Only install hooks, skip database initialization
        #[arg(long)]
        hooks_only: bool,

        /// Configure OpenTelemetry env vars for token tracking
        #[arg(long, conflicts_with = "no_otel")]
        otel: bool,

        /// Port for OTel server (default: 4318)
        #[arg(long, default_value = "4318")]
        otel_port: u16,

        /// Remove OTel configuration (disables token tracking)
        #[arg(long, conflicts_with = "otel")]
        no_otel: bool,
    },

    /// Deactivate fyi for AI coding frameworks
    Deactivate {
        /// Frameworks to deactivate. If omitted, deactivates all frameworks that have fyi active.
        #[arg(value_name = "FRAMEWORKS")]
        frameworks: Vec<String>,

        /// Remove from project config instead of global
        #[arg(long, conflicts_with = "settings_local")]
        local: bool,

        /// Remove from project local config
        #[arg(long, conflicts_with = "local")]
        settings_local: bool,

        /// Print what would be removed without modifying files
        #[arg(long)]
        print: bool,
    },

    /// Log an event (called by hooks, reads JSON from stdin or argument)
    Log {
        /// Event type (SessionStart, PreToolUse, etc.)
        /// For Codex CLI, this can be omitted - the event type is extracted from the JSON payload's "type" field
        event_type: Option<String>,

        /// JSON payload (if not provided, reads from stdin)
        /// Used by Codex CLI which passes JSON as a command-line argument
        json_payload: Option<String>,

        /// AI framework logging the event (auto-detected if not specified)
        #[arg(long, short = 'f')]
        framework: Option<String>,
    },

    /// Show recent events
    Show {
        /// Number of events to show
        #[arg(short = 'n', long, default_value = "20")]
        limit: usize,

        /// Filter by session ID
        #[arg(short, long)]
        session: Option<String>,

        /// Filter by event type
        #[arg(short = 't', long = "type")]
        event_type: Option<String>,

        /// Filter by permission mode (default, plan, acceptEdits, bypassPermissions)
        #[arg(short, long)]
        mode: Option<String>,

        /// Filter by framework (claude, cursor, gemini)
        #[arg(long, short = 'f')]
        framework: Option<String>,

        /// Output as JSON
        #[arg(long)]
        json: bool,
    },

    /// Run garbage collection to remove old events
    Gc {
        /// Show what would be removed without actually removing
        #[arg(long)]
        dry_run: bool,

        /// Retention period (e.g., "30d", "7d", "24h"). Default: 30d
        #[arg(short, long)]
        retention: Option<String>,
    },

    /// Watch for new events in real-time
    Watch {
        /// Filter by session ID
        #[arg(short, long)]
        session: Option<String>,

        /// Filter by event type
        #[arg(short = 't', long = "type")]
        event_type: Option<String>,

        /// Filter by permission mode (default, plan, acceptEdits, bypassPermissions)
        #[arg(short, long)]
        mode: Option<String>,

        /// Filter by framework (claude, cursor, gemini)
        #[arg(long, short = 'f')]
        framework: Option<String>,

        /// Poll interval in milliseconds
        #[arg(long, default_value = "500")]
        poll_ms: u64,
    },

    /// Manage the OpenTelemetry server for token tracking
    #[command(subcommand)]
    Otel(OtelCommands),

    /// Show session statistics including token usage and context size
    Session {
        /// Session ID or PID to show details for
        session_or_pid: String,

        /// Output as JSON
        #[arg(long)]
        json: bool,
    },
}

/// Subcommands for managing the OpenTelemetry server
#[derive(Subcommand, Debug)]
pub enum OtelCommands {
    /// Start the OTel server (daemonized)
    Start {
        /// Port to listen on
        #[arg(short, long, default_value = "4318")]
        port: u16,
    },

    /// Stop the running OTel server
    Stop {
        /// Port to stop
        #[arg(short, long, default_value = "4318")]
        port: u16,
    },

    /// Restart the OTel server
    Restart {
        /// Port to restart on
        #[arg(short, long, default_value = "4318")]
        port: u16,
    },

    /// Show whether OTel server is running and on which port
    Status {
        /// Port to check
        #[arg(short, long, default_value = "4318")]
        port: u16,
    },

    /// Run OTel server in foreground (for debugging)
    Run {
        /// Port to listen on
        #[arg(short, long, default_value = "4318")]
        port: u16,
    },
}
