//! Error types for Aphoria.

use std::path::PathBuf;
use thiserror::Error;

/// Result type for Aphoria operations.
pub type Result<T> = std::result::Result<T, AphoriaError>;

/// Errors that can occur during Aphoria operations.
#[derive(Error, Debug)]
pub enum AphoriaError {
    /// Configuration file error.
    #[error("Configuration error: {0}")]
    Config(String),

    /// Configuration file not found.
    #[error("Configuration file not found: {0}")]
    ConfigNotFound(PathBuf),

    /// Invalid configuration format.
    #[error("Invalid configuration: {0}")]
    ConfigParse(#[from] toml::de::Error),

    /// Project not found.
    #[error("Project not found: {0}")]
    ProjectNotFound(PathBuf),

    /// File system error.
    #[error("File system error: {0}")]
    Io(#[from] std::io::Error),

    /// Walker error during file traversal.
    #[error("Walker error: {0}")]
    Walker(String),

    /// Extractor error during claim extraction.
    #[error("Extraction error in {extractor}: {message}")]
    Extraction {
        /// The extractor that failed.
        extractor: String,
        /// The error message.
        message: String,
    },

    /// Episteme storage error.
    #[error("Storage error: {0}")]
    Storage(String),

    /// Query error during conflict detection.
    #[error("Query error: {0}")]
    Query(String),

    /// Report generation error.
    #[error("Report error: {0}")]
    Report(String),

    /// Baseline not found.
    #[error("No baseline set. Run `aphoria baseline` first.")]
    NoBaseline,

    /// Initialization error.
    #[error("Initialization error: {0}")]
    Init(String),

    /// Acknowledgment error.
    #[error("Acknowledgment error: {0}")]
    Acknowledge(String),

    /// RFC fetch error.
    #[error("Failed to fetch RFC {rfc}: {message}")]
    RfcFetch {
        /// The RFC number that failed to fetch.
        rfc: u32,
        /// The error message.
        message: String,
    },

    /// OWASP cheat sheet fetch error.
    #[error("Failed to fetch OWASP cheat sheet {sheet}: {message}")]
    OwaspFetch {
        /// The cheat sheet that failed to fetch.
        sheet: String,
        /// The error message.
        message: String,
    },

    /// Corpus build error.
    #[error("Corpus build error: {0}")]
    CorpusBuild(String),

    /// Not a git repository.
    #[error("Not a git repository (or any parent directories)")]
    NotGitRepo,

    /// Git command failed.
    #[error("Failed to run git: {0}")]
    GitCommand(String),

    /// Hosted mode error (server unreachable, auth failure, etc.).
    #[error("Hosted mode error: {0}")]
    Hosted(String),

    /// Invalid declarative extractor definition.
    #[error("Invalid declarative extractor '{name}': {message}")]
    DeclarativeExtractor {
        /// The name of the extractor (or "(empty)" if no name was provided).
        name: String,
        /// The validation error message.
        message: String,
    },

    /// LLM API error (network, auth, rate limit).
    #[error("LLM API error: {0}")]
    LlmApi(String),

    /// LLM response parsing error.
    #[error("LLM response parse error: {0}")]
    LlmParse(String),

    /// Learning store error (pattern persistence, cache access).
    #[error("Learning store error: {0}")]
    LearningStore(String),

    /// Promotion pipeline error (candidate generation, validation, writing).
    #[error("Promotion error: {0}")]
    Promotion(String),

    /// Regex generation error (LLM returned invalid regex).
    #[error("Regex generation error: {0}")]
    RegexGeneration(String),

    /// Shadow mode testing error.
    #[error("Shadow mode error: {0}")]
    Shadow(String),

    /// Invalid expiry specification (e.g., invalid duration or date format).
    #[error("Invalid expiry: {0}")]
    InvalidExpiry(String),

    /// Governance workflow error (approval pending, rejected, or configuration issue).
    #[error("Governance error: {0}")]
    Governance(String),
}
