//! Command-line argument types.

use std::path::PathBuf;

/// Scan mode determines whether to persist claims to Episteme storage.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ScanMode {
    /// Fast in-memory scan without persistence.
    /// Uses EphemeralDetector for conflict detection.
    /// Does not support diff/baseline features.
    #[default]
    Ephemeral,

    /// Full scan with persistence to Episteme storage.
    /// Enables diff, baseline, and alias creation features.
    /// Slower due to WAL, store, and ingestion initialization.
    Persistent,
}

/// File source determines which files to scan.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum FileSource {
    /// Scan all files in the project (default).
    #[default]
    All,

    /// Scan only git-staged files (for pre-commit hooks).
    /// Uses `git diff --cached --name-only --diff-filter=ACMR`.
    Staged,
}

/// Arguments for the scan command.
#[derive(Debug, Clone)]
pub struct ScanArgs {
    /// Path to the project root.
    pub path: PathBuf,

    /// Output format (table, json, sarif, markdown).
    pub format: String,

    /// Whether to enable non-zero exit codes on conflicts.
    pub exit_code_enabled: bool,

    /// Scan mode: Ephemeral (default, fast) or Persistent (for diff/baseline).
    pub mode: ScanMode,

    /// Enable debug output showing conflict resolution traces.
    pub debug: bool,

    /// Enable write-back of observations to local Episteme.
    /// When enabled, claims with no authority conflict are written as Tier 4
    /// (Community) assertions, creating "project memory" for future drift detection.
    /// Requires `mode == Persistent`.
    pub sync: bool,

    /// File source: All (default) or Staged (for pre-commit hooks).
    pub file_source: FileSource,

    /// Enable benchmark mode with timing breakdown.
    /// When enabled, timing measurements are captured for each scan phase
    /// and included in the output.
    pub benchmark: bool,

    /// Show all extracted claims in the output.
    /// When enabled, all claims (not just conflicts) are included in the
    /// scan result, sorted by file path and line number.
    pub show_claims: bool,
}

/// Arguments for the acknowledge command.
#[derive(Debug, Clone)]
pub struct AcknowledgeArgs {
    /// The concept path to acknowledge.
    pub concept_path: String,

    /// Reason for acknowledgment.
    pub reason: String,

    /// Optional expiry for acknowledgment (e.g., "90d" or "2026-12-31").
    ///
    /// When an acknowledgment expires, the conflict resurfaces as BLOCK/FLAG.
    /// The expired acknowledgment is preserved for audit trail.
    pub expires: Option<String>,
}

/// Arguments for the bless command.
///
/// Unlike `ack` (which creates a suppression assertion), `bless` creates an
/// assertion with the actual predicate/value that becomes the authoritative standard.
#[derive(Debug, Clone)]
pub struct BlessArgs {
    /// The concept path to bless (e.g., "code://rust/grpc/tls").
    pub concept_path: String,

    /// The predicate being defined (e.g., "enabled", "min_version").
    pub predicate: String,

    /// The value for this standard (e.g., "true", "1.2").
    pub value: String,

    /// Reason/description for why this is the standard.
    pub reason: String,
}

/// Arguments for the update command.
///
/// Records an intentional policy change as a new baseline value for a concept.
/// Unlike `ack` (which marks a conflict as reviewed), `update` records the
/// new intended value for future drift detection.
#[derive(Debug, Clone)]
pub struct UpdateArgs {
    /// The concept path to update (e.g., "db/pool_size").
    pub concept_path: String,

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

    /// Reason for the update (e.g., "Scaling for Black Friday").
    pub reason: String,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scan_mode_default() {
        assert_eq!(ScanMode::default(), ScanMode::Ephemeral);
    }

    #[test]
    fn test_file_source_default() {
        assert_eq!(FileSource::default(), FileSource::All);
    }
}
