//! Type definitions for the guardrails policy engine.
//!
//! All types derive `Debug, Clone, Serialize, Deserialize` for structured
//! JSON output and programmatic consumption.

use serde::{Deserialize, Serialize};

/// Result of policy evaluation against a SQL query.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyResult {
    /// Whether the query is allowed by all policies
    pub allowed: bool,

    /// Blocking policy violations
    pub violations: Vec<PolicyViolation>,

    /// Non-blocking policy warnings
    pub warnings: Vec<PolicyWarning>,

    /// Number of policy rules evaluated
    pub policies_evaluated: usize,

    /// Audit trail entry for this evaluation
    pub audit: AuditEntry,
}

/// A blocking policy violation.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyViolation {
    /// Rule name that triggered this violation
    pub rule: String,

    /// Policy category
    pub category: PolicyCategory,

    /// Violation severity
    pub severity: ViolationSeverity,

    /// Human-readable description of the violation
    pub message: String,

    /// Suggested remediation action
    #[serde(skip_serializing_if = "Option::is_none")]
    pub remediation: Option<String>,

    /// Structured detail about what triggered the violation
    pub detail: ViolationDetail,
}

/// A non-blocking policy warning.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyWarning {
    /// Rule name that triggered this warning
    pub rule: String,

    /// Policy category
    pub category: PolicyCategory,

    /// Human-readable warning message
    pub message: String,
}

/// Categories of policy rules.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PolicyCategory {
    /// Cost and performance controls
    CostControl,
    /// Data protection and access control
    DataProtection,
    /// Query pattern restrictions
    QueryPatterns,
    /// Tag-based rules
    TagRules,
    /// User-defined custom rules
    Custom,
}

/// Severity of a policy violation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ViolationSeverity {
    /// Blocking error
    Error,
    /// Non-blocking warning
    Warning,
    /// Informational note
    Info,
}

/// Structured details about why a violation occurred.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ViolationDetail {
    /// A blocked column was accessed
    BlockedColumn {
        /// Table containing the blocked column
        table: String,
        /// The blocked column name
        column: String,
    },
    /// A blocked table was accessed
    BlockedTable {
        /// The blocked table name
        table: String,
    },
    /// A metric exceeded its configured limit
    ExceededLimit {
        /// The metric that was exceeded
        metric: String,
        /// The configured limit
        limit: usize,
        /// The actual value observed
        actual: usize,
    },
    /// A blocked SQL statement type was used
    BlockedStatement {
        /// The blocked statement type
        statement: String,
    },
    /// A blocked pattern was detected
    BlockedPattern {
        /// Description of the blocked pattern
        pattern: String,
    },
    /// A tag-based rule was violated
    TagViolation {
        /// The tag that triggered the violation
        tag: String,
        /// Table containing the tagged column
        table: String,
        /// The tagged column name
        column: String,
    },
    /// A custom rule violation
    CustomRule {
        /// Freeform detail
        detail: String,
    },
}

/// Audit trail entry for compliance and logging.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEntry {
    /// ISO 8601 timestamp of the evaluation
    pub timestamp: String,

    /// First 16 characters of the SHA-256 hash of the SQL query
    pub sql_hash: String,

    /// Whether the query was allowed
    pub allowed: bool,

    /// Number of violations found
    pub violation_count: usize,

    /// Number of warnings found
    pub warning_count: usize,

    /// Number of policy rules checked
    pub policies_checked: usize,

    /// Time taken for evaluation in milliseconds
    pub evaluation_time_ms: u64,
}
