//! Extractor-related configuration types.

use std::path::PathBuf;

use serde::Deserialize;

use crate::extractors::DeclarativeExtractorDef;

/// Extractor configuration.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct ExtractorConfig {
    /// Enabled extractors.
    pub enabled: Vec<String>,

    /// Disabled extractors (alternative to enabled list).
    pub disabled: Vec<String>,

    /// Timeout extractor settings.
    pub timeout_config: TimeoutExtractorConfig,

    /// Dependency version extractor settings.
    pub dep_versions: DepVersionConfig,

    /// Self-audit extractor settings (opt-in, for dogfooding).
    pub self_audit: SelfAuditConfig,

    /// High-entropy secrets extractor settings.
    pub entropy: EntropyConfig,

    /// Inline claim marker extractor settings (opt-in).
    pub inline_markers: InlineMarkerConfig,

    /// Declarative extractors defined in config.
    ///
    /// These are custom pattern-based extractors that users define via TOML
    /// without writing Rust code. Each declarative extractor specifies a
    /// regex pattern and claim configuration.
    ///
    /// # Example
    ///
    /// ```toml
    /// [[extractors.declarative]]
    /// name = "deprecated_api_v1"
    /// description = "Detects usage of deprecated v1 API endpoints"
    /// languages = ["go", "rust", "python"]
    /// pattern = '/api/v1/\w+'
    /// claim.subject = "api/deprecated_endpoint"
    /// claim.predicate = "version"
    /// claim.value = "v1"
    /// confidence = 1.0
    /// ```
    #[serde(default)]
    pub declarative: Vec<DeclarativeExtractorDef>,
}

/// Timeout extractor configuration.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct TimeoutExtractorConfig {
    /// Minimum reasonable timeout in milliseconds.
    pub min_reasonable_ms: u64,

    /// Maximum reasonable timeout in milliseconds.
    pub max_reasonable_ms: u64,
}

/// Dependency version extractor configuration.
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct DepVersionConfig {
    /// Enable dependency version extraction (opt-in).
    ///
    /// Default: false to reduce noise in output.
    /// Enable this if you want dependency inventory for advisory lookup.
    pub enabled: bool,

    /// Path to advisory database.
    pub advisory_db: PathBuf,
}

/// Self-audit extractor configuration (opt-in).
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub struct SelfAuditConfig {
    /// Enable self-audit extraction (opt-in).
    ///
    /// Default: false. Enable this to dogfood Aphoria on its own codebase.
    pub enabled: bool,
}

/// High-entropy secrets extractor configuration.
///
/// Controls the entropy thresholds used to detect potential secrets.
/// Higher thresholds reduce false positives but may miss some secrets.
///
/// # Example
///
/// ```toml
/// [extractors.entropy]
/// min_entropy = 4.5
/// min_charset_variety = 0.4
/// min_length = 20
/// max_length = 200
/// ```
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct EntropyConfig {
    /// Minimum Shannon entropy to consider a string as a potential secret.
    ///
    /// - AWS keys: ~5.0 bits
    /// - UUIDs: ~3.8 bits
    /// - Random base64: ~5.5 bits
    ///
    /// Default: 4.5 (catches most secrets while excluding UUIDs)
    pub min_entropy: f32,

    /// Minimum charset variety (unique chars / total chars).
    ///
    /// Secrets typically have high variety (0.4+), while UUIDs are lower (~0.25).
    /// Default: 0.4
    pub min_charset_variety: f32,

    /// Minimum string length to analyze.
    ///
    /// Short strings are likely config values, not secrets.
    /// Default: 20
    pub min_length: usize,

    /// Maximum string length to analyze.
    ///
    /// Very long strings are likely data blobs, not secrets.
    /// Default: 200
    pub max_length: usize,
}

/// Inline claim marker extractor configuration (opt-in).
///
/// Detects `@aphoria:claim` markers in code comments, allowing developers
/// to capture claim intent while writing code.
///
/// # Example
///
/// ```toml
/// [extractors.inline_markers]
/// enabled = true
/// sync_to_pending = true
/// ```
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct InlineMarkerConfig {
    /// Enable inline marker extraction (opt-in).
    ///
    /// Default: false. Set to true to detect `@aphoria:claim` markers in comments.
    pub enabled: bool,

    /// Auto-sync detected markers to `.aphoria/pending_markers.toml` during scan.
    ///
    /// Default: true (when enabled). Markers are automatically persisted for
    /// later formalization via `aphoria claims formalize-marker`.
    #[serde(default = "default_true")]
    pub sync_to_pending: bool,
}

fn default_true() -> bool {
    true
}
