//! Request DTOs for Aphoria endpoints.

use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

use super::types::{CommunityObservationDto, ObservationDto};

// ============================================================================
// Bless Endpoint DTOs
// ============================================================================

/// Request to bless a code pattern as the authoritative standard.
///
/// Unlike `acknowledge` (which creates a suppression), `bless` creates an
/// assertion with the actual predicate and value that becomes the authoritative
/// standard. Blessed patterns can be exported as Trust Packs.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct BlessRequest {
    /// The concept path to bless (e.g., "code://rust/grpc/tls").
    pub concept_path: String,

    /// The predicate being defined (e.g., "enabled", "min_version").
    pub predicate: String,

    /// The value for this standard (e.g., "true", "1.2").
    pub value: String,

    /// Reason/description for why this is the standard.
    pub reason: String,
}

// ============================================================================
// Export Policy DTOs
// ============================================================================

/// Request to export policy assertions as a Trust Pack.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ExportPolicyRequest {
    /// Name for the Trust Pack (e.g., "acme-security-policy").
    pub name: String,

    /// Optional description for the pack.
    #[serde(default)]
    pub description: Option<String>,

    /// Optional output path. If not provided, returns pack data inline.
    #[serde(default)]
    pub output_path: Option<String>,
}

// ============================================================================
// Import Policy DTOs
// ============================================================================

/// Request to import a Trust Pack.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ImportPolicyRequest {
    /// Path to the Trust Pack file.
    pub pack_path: String,
}

// ============================================================================
// Scan Endpoint DTOs
// ============================================================================

/// Request to scan a project for conflicts.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ScanRequest {
    /// Path to the project root to scan.
    pub target_path: String,

    /// Output format: "table", "json", "sarif", "markdown".
    #[serde(default = "default_format")]
    pub format: String,

    /// Whether to return 422 on BLOCK findings.
    #[serde(default)]
    pub fail_on_flag: bool,

    /// Minimum severity to report: "pass", "flag", "block".
    #[serde(default)]
    pub min_severity: Option<String>,

    /// Enable debug output showing conflict resolution traces.
    #[serde(default)]
    pub debug: bool,
}

fn default_format() -> String {
    "json".to_string()
}

// ============================================================================
// Push Observations Endpoint DTOs (Hosted Mode)
// ============================================================================

/// Request to push observations from a hosted Aphoria client.
///
/// Teams running Aphoria in hosted mode push observations to a central
/// StemeDB server for pattern aggregation across projects.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PushObservationsRequest {
    /// The observations to store.
    pub observations: Vec<ObservationDto>,

    /// Project identifier (e.g., "billing-service").
    pub project_id: String,

    /// Optional team identifier for multi-team servers.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub team_id: Option<String>,

    /// Client version for debugging (e.g., "0.1.0").
    pub client_version: String,
}

// ============================================================================
// Community Corpus Contribution DTOs
// ============================================================================

/// Request to push anonymized observations to the community corpus.
///
/// When teams opt-in to community sharing, their scan observations are
/// anonymized (project names wildcarded, file paths stripped) and pushed
/// to a central corpus to help establish community consensus on patterns.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct PushCommunityObservationsRequest {
    /// The anonymized observations to share.
    pub observations: Vec<CommunityObservationDto>,

    /// Hash of the project (for deduplication, NOT the actual project name).
    /// This is BLAKE3 hash of the project name to prevent name leakage.
    pub project_hash: String,

    /// Client version for debugging.
    pub client_version: String,
}

/// Request to get popular patterns from the community corpus.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GetPatternsRequest {
    /// Minimum number of projects that must report a pattern (default: 3).
    #[serde(default = "default_min_projects")]
    pub min_projects: u64,

    /// Maximum number of patterns to return (default: 100).
    #[serde(default = "default_limit")]
    pub limit: usize,

    /// Filter by subject prefix (e.g., "code://rust/*/tls/").
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subject_prefix: Option<String>,
}

fn default_min_projects() -> u64 {
    3
}

fn default_limit() -> usize {
    100
}
