//! Redaction policy types for context pack construction.

use serde::{Deserialize, Serialize};

/// Context pack audience/mode.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum PackMode {
    /// Default mode for packs intended for external model consumers.
    #[default]
    External,
    /// Operator-local mode. Raw event payloads still require explicit opt-in.
    Operator,
}

/// How selected content is represented in the pack body.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ContentRedaction {
    /// References, summaries, and scope fields only.
    Abstracted,
    /// Full selected content is allowed by policy.
    Full,
}

/// Raw event payload handling for a pack.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RawEventPayloadPolicy {
    /// Raw event payloads are removed before serialization.
    Excluded,
    /// Raw event payloads may appear only after operator-mode explicit opt-in.
    OperatorOptIn,
}

/// Sensitivity tier attached to candidate material before pack inclusion.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Sensitivity {
    /// Safe for public/external inclusion after normal abstraction.
    Public,
    /// Internal operational detail.
    Internal,
    /// Personal/private material.
    Personal,
    /// Secret material. Never allowed in pack body.
    Secret,
}

/// Policy recorded on every context pack.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RedactionPolicy {
    /// Stable policy identifier for audit/replay.
    pub policy_id: String,
    /// Policy version recorded with the pack.
    pub policy_version: u16,
    /// Pack body content representation.
    pub content: ContentRedaction,
    /// Raw event payload handling.
    pub raw_event_payloads: RawEventPayloadPolicy,
}

impl RedactionPolicy {
    /// Default external policy from BUILD_SPEC §2.2: redacted/abstracted, no raw events.
    #[must_use]
    pub fn external_default() -> Self {
        Self {
            policy_id: "context_pack.external.redacted_abstracted".to_string(),
            policy_version: 1,
            content: ContentRedaction::Abstracted,
            raw_event_payloads: RawEventPayloadPolicy::Excluded,
        }
    }

    /// Operator policy after an explicit raw-payload opt-in.
    #[must_use]
    pub fn operator_with_raw_payload_opt_in() -> Self {
        Self {
            policy_id: "context_pack.operator.raw_payload_opt_in".to_string(),
            policy_version: 1,
            content: ContentRedaction::Full,
            raw_event_payloads: RawEventPayloadPolicy::OperatorOptIn,
        }
    }
}

impl Default for RedactionPolicy {
    fn default() -> Self {
        Self::external_default()
    }
}
