use serde::Serialize;

#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum DiagnosticSeverity {
    Info,
    Warning,
}

#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "snake_case")]
pub enum QualityFindingKind {
    MalformedFrontmatter,
    FrontmatterScalarListField,
    EmptyListItem,
    InvalidStatus,
    UnknownType,
    TypeNormalized,
    ConflictingTypeKind,
    UnknownFrontmatterField,
    /// A source file authored a RUNTIME-TRUTH field (`tier`, `confidence`, `score`, `span`,
    /// `last_used`, `ground_count`, `freshness`). Authored files may declare identity and intent;
    /// they must never claim what Eidos computes. Warned, and the field is ignored in compilation.
    AuthoredRuntimeTruth,
    TypeKindMissing,
    UnresolvedWikilink,
    BrokenInternalMarkdownLink,
    MalformedInternalMarkdownLink,
    MissingIndex,
    EmptyIndex,
    BrokenIndexLink,
    MalformedLogDateHeading,
    DuplicatePathIdentity,
    UnresolvedFrontmatterTarget,
    OrphanNode,
    IsolatedNode,
    DuplicateTitle,
    DuplicateAlias,
    AliasDuplicatesTitle,
    DuplicateQueryExample,
    QueryExampleDuplicatesTitle,
    TitleMissing,
    SummaryMissing,
    NoSearchableBody,
    WeakDoc,
}

#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "snake_case")]
pub enum Repairability {
    None,
    Advisory,
    AutoProposable,
}

#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct QualityFinding {
    pub finding_id: String,
    pub kind: QualityFindingKind,
    pub severity: DiagnosticSeverity,
    pub repairability: Repairability,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub node_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub field: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub target: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_action: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub repair_tool: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub suggested_replacement: Option<String>,
    pub message: String,
}

#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
pub struct NodeQualityScore {
    pub node_id: String,
    pub score: u8,
    pub max_score: u8,
    pub passed: Vec<String>,
    pub missing: Vec<String>,
}

#[derive(Debug, Clone, Copy)]
pub struct QualityAuditOptions {
    pub validate_relation_targets: bool,
}

impl Default for QualityAuditOptions {
    fn default() -> Self {
        Self {
            validate_relation_targets: true,
        }
    }
}
