//! Query audit trail data structures.

use rkyv::{Archive, Deserialize, Serialize};

use super::{EntityId, EpochId, Hash, QueryId, RelationId};
use crate::types::LifecycleStage;

/// An audit record for a query operation.
///
/// Stored at `AUD:{query_id}` to enable "Why did you think that?" debugging.
/// Every read operation is logged with full provenance for incident investigation.
///
/// # Use Case
///
/// At 3am, production is broken. An agent deployed wrong config.
/// The SRE needs to know: What did the agent query? What result did it get?
/// What assertions contributed to that answer?
///
/// # Example
///
/// ```ignore
/// // Trace an agent's decision
/// GET /v1/audit/queries?agent_id=deployment-agent&from=1704067200
///
/// // Get full reasoning trace for a specific query
/// GET /v1/audit/query/{query_id}
/// ```
#[derive(Archive, Deserialize, Serialize, Debug, Clone, PartialEq)]
#[archive(check_bytes)]
pub struct QueryAudit {
    /// Unique identifier for this query (content-addressed hash of serialized params + timestamp).
    pub query_id: QueryId,
    /// The Ed25519 Public Key of the querying agent (extracted from request header, if present).
    pub agent_id: Option<[u8; 32]>,
    /// Unix timestamp when the query was executed.
    pub timestamp: u64,
    /// The query parameters that were used.
    pub params: QueryParams,
    /// Hash of the winning assertion (None if no results).
    pub result_hash: Option<Hash>,
    /// Confidence score of the resolution (0.0 to 1.0).
    pub result_confidence: f32,
    /// The assertions that contributed to this result, with their influence weights.
    pub contributing_assertions: Vec<ContributingAssertion>,
}

/// Query parameters captured for audit purposes.
///
/// This mirrors the query filters that were applied during resolution.
#[derive(Archive, Deserialize, Serialize, Debug, Clone, PartialEq)]
#[archive(check_bytes)]
pub struct QueryParams {
    /// Filter by subject entity.
    pub subject: Option<EntityId>,
    /// Filter by predicate/relation.
    pub predicate: Option<RelationId>,
    /// Filter by lifecycle stage.
    pub lifecycle: Option<LifecycleStage>,
    /// Filter by epoch (if specified).
    pub epoch: Option<EpochId>,
    /// Which lens was used for conflict resolution.
    pub lens: Option<String>,
}

/// An assertion that contributed to a query result.
///
/// Captures not just which assertions were considered, but how much
/// each one influenced the final answer.
#[derive(Archive, Deserialize, Serialize, Debug, Clone, PartialEq)]
#[archive(check_bytes)]
pub struct ContributingAssertion {
    /// Hash of the assertion.
    pub assertion_hash: Hash,
    /// How much this assertion influenced the result (0.0 to 1.0).
    /// For the winner, this is typically 1.0.
    /// For candidates in vote-based lenses, this is the normalized vote weight.
    pub weight: f32,
    /// Hash of the source evidence for this assertion.
    pub source_hash: Hash,
    /// Lifecycle stage of this assertion at query time.
    pub lifecycle: LifecycleStage,
}
