//! CLI argument definitions for Aphoria
//!
//! This module is split into submodules to keep file sizes manageable:
//! - `extractors`: Extractor and shadow mode commands
//! - `governance`: Governance and Audit commands
//! - `lifecycle`: Lifecycle and Migration commands
//! - `patterns`: Pattern and Eval commands
//! - `scope`: Scope commands

mod extractors;
mod governance;
mod lifecycle;
mod patterns;
mod scope;

pub use extractors::ExtractorCommands;
pub use governance::{AuditCommands, GovernanceCommands};
pub use lifecycle::{LifecycleCommands, MigrationCommands};
pub use patterns::{EvalCommands, PatternCommands};
pub use scope::ScopeCommands;

use std::path::PathBuf;

use clap::{Parser, Subcommand};

/// A code-level truth linter powered by Episteme.
///
/// Aphoria scans a codebase, extracts the decisions embedded in config and code,
/// and checks them against authoritative sources. It finds the places where what
/// your code *does* contradicts what the specs *say*.
#[derive(Parser)]
#[command(name = "aphoria")]
#[command(version, about, long_about = None)]
pub struct Cli {
    /// Path to aphoria.toml configuration file
    #[arg(short, long, global = true)]
    pub config: Option<PathBuf>,

    /// Enable verbose logging (shows internal tracing output)
    #[arg(short, long, global = true)]
    pub verbose: bool,

    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Subcommand)]
pub enum Commands {
    /// Scan a project for epistemic drift
    Scan {
        /// Path to the project root to scan
        #[arg(default_value = ".")]
        path: PathBuf,

        /// Output format: table, json, sarif, markdown
        #[arg(short, long, default_value = "table")]
        format: String,

        /// Exit with non-zero code if conflicts found
        #[arg(long)]
        exit_code: bool,

        /// Use stricter thresholds (FLAG at 0.3, BLOCK at 0.5)
        #[arg(long)]
        strict: bool,

        /// Persist claims to Episteme storage (enables diff/baseline features).
        /// Without this flag, scans are ephemeral and fast.
        #[arg(long)]
        persist: bool,

        /// Enable debug output showing conflict resolution traces.
        #[arg(long)]
        debug: bool,

        /// Enable write-back of observations to local Episteme (requires --persist).
        #[arg(long)]
        sync: bool,

        /// Scan only git-staged files (for pre-commit hooks).
        #[arg(long)]
        staged: bool,

        /// Preview what would be shared with the community corpus.
        #[arg(long)]
        community_preview: bool,

        /// Run performance benchmark with timing breakdown.
        #[arg(long)]
        benchmark: bool,

        /// Show all extracted claims in the output
        #[arg(long)]
        show_claims: bool,
    },

    /// Manage acknowledgments (mark conflicts as intentional)
    Ack {
        #[command(subcommand)]
        command: AckCommands,
    },

    /// Bless a code pattern as the authoritative standard
    Bless {
        /// The concept path to bless
        concept_path: String,

        /// The predicate (e.g., "enabled", "min_version")
        #[arg(short, long)]
        predicate: String,

        /// The value (e.g., "true", "1.2")
        #[arg(short = 'V', long)]
        value: String,

        /// Reason/description for this standard
        #[arg(short, long)]
        reason: String,
    },

    /// Record an intentional configuration change as a policy update
    Update {
        /// The concept path being updated
        concept_path: String,

        /// The new value for this concept
        value: String,

        /// Reason for the update
        #[arg(short, long)]
        reason: String,
    },

    /// Set the current scan as the baseline
    Baseline,

    /// Show changes since last baseline
    Diff,

    /// Show current scan status
    Status,

    /// Initialize Aphoria with authoritative corpus
    Init,

    /// Manage the authoritative corpus
    Corpus {
        #[command(subcommand)]
        command: CorpusCommands,
    },

    /// Manage the research agent for filling corpus gaps
    Research {
        #[command(subcommand)]
        command: ResearchCommands,
    },

    /// Manage federated policies (Trust Packs)
    Policy {
        #[command(subcommand)]
        command: PolicyCommands,
    },

    /// Manage learned patterns and extractor promotion
    Extractors {
        #[command(subcommand)]
        command: ExtractorCommands,
    },

    /// Evaluate LLM prompt effectiveness
    Eval {
        #[command(subcommand)]
        command: EvalCommands,
    },

    /// Manage cross-project pattern learning
    Patterns {
        #[command(subcommand)]
        command: PatternCommands,
    },

    /// Manage knowledge scopes and inheritance
    Scope {
        #[command(subcommand)]
        command: ScopeCommands,
    },

    /// Manage knowledge lifecycle (deprecation, archival)
    Lifecycle {
        #[command(subcommand)]
        command: LifecycleCommands,
    },

    /// Track migration progress for deprecated patterns
    Migrations {
        #[command(subcommand)]
        command: MigrationCommands,
    },

    /// Manage approval workflows for pattern promotion
    Governance {
        #[command(subcommand)]
        command: GovernanceCommands,
    },

    /// View and export audit trails for compliance
    Audit {
        #[command(subcommand)]
        command: AuditCommands,
    },
}

#[derive(Subcommand)]
pub enum AckCommands {
    /// Create a new acknowledgment for a conflict
    Add {
        /// The concept path to acknowledge
        concept_path: String,

        /// Reason for acknowledgment
        #[arg(short, long)]
        reason: String,

        /// Optional expiry for acknowledgment (e.g., "90d" or "2026-12-31")
        #[arg(long, alias = "expires-at")]
        expires: Option<String>,
    },

    /// Export acknowledgments to .aphoria/acks.toml for version control
    Export {
        /// Output path (default: .aphoria/acks.toml)
        #[arg(short, long)]
        output: Option<PathBuf>,
    },

    /// Import acknowledgments from .aphoria/acks.toml
    Import {
        /// Input path (default: .aphoria/acks.toml)
        #[arg(short, long)]
        input: Option<PathBuf>,
    },
}

#[derive(Subcommand)]
pub enum CorpusCommands {
    /// Build the authoritative corpus from configured sources
    Build {
        /// Only include specific sources (comma-separated)
        #[arg(long)]
        only: Option<String>,

        /// Run in offline mode (skip sources requiring network)
        #[arg(long)]
        offline: bool,

        /// Clear cache before building
        #[arg(long)]
        clear_cache: bool,
    },

    /// List available corpus sources
    List,
}

#[derive(Subcommand)]
pub enum ResearchCommands {
    /// Run the research agent to fill corpus gaps
    Run {
        /// Minimum projects that must report a gap before researching
        #[arg(short, long, default_value = "3")]
        threshold: u32,

        /// Use strict quality validation
        #[arg(long)]
        strict: bool,

        /// Prune old gaps before researching
        #[arg(long)]
        prune: bool,

        /// Maximum age of gaps to consider in days
        #[arg(long, default_value = "90")]
        max_age: u64,
    },

    /// Show research agent status and gap statistics
    Status,

    /// List gaps eligible for research
    Gaps {
        /// Minimum projects that must report a gap
        #[arg(short, long, default_value = "1")]
        threshold: u32,

        /// Show only gaps ready for research (seen in 3+ projects)
        #[arg(long)]
        ready: bool,
    },
}

#[derive(Subcommand)]
pub enum PolicyCommands {
    /// Export acknowledged conflicts as a Trust Pack
    Export {
        /// Name of the policy pack
        #[arg(long)]
        name: String,

        /// Output path for the pack file
        #[arg(short, long)]
        output: PathBuf,
    },

    /// Import a Trust Pack into the local Episteme
    Import {
        /// Path to the .pack file
        file: PathBuf,
    },

    /// Re-sign a Trust Pack with a new key
    Resign {
        /// Path to the .pack file to re-sign
        file: PathBuf,

        /// Output path for the re-signed pack
        #[arg(short, long)]
        output: PathBuf,

        /// Path to new signing key
        #[arg(long)]
        key: Option<PathBuf>,

        /// Reason for re-signing (for audit trail)
        #[arg(long)]
        reason: Option<String>,

        /// Preserve signature chain for audit trail
        #[arg(long, default_value = "true")]
        chain_signatures: bool,
    },
}
