//! Research Agent for Aphoria.
//!
//! The Research Agent detects gaps in authoritative coverage and researches
//! official documentation to fill those gaps. This module provides:
//!
//! - **Gap Detection**: Identifies code claims with no authoritative coverage
//! - **Gap Storage**: Persists gaps with tracking metadata (project count, first seen)
//! - **Research Trigger**: Dispatches research when gaps reach threshold
//! - **Claim Extraction**: Parses official documentation for normative claims
//! - **Quality Validation**: Ensures extracted claims meet quality standards
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────────┐
//! │                      Research Agent Flow                             │
//! │                                                                      │
//! │  ┌────────────┐   ┌──────────────┐   ┌─────────────────────────────┐│
//! │  │ Gap        │──▶│ Gap Store    │──▶│ Research Trigger            ││
//! │  │ Detector   │   │ (SQLite)     │   │ (threshold: 3 projects)     ││
//! │  └────────────┘   └──────────────┘   └─────────────────────────────┘│
//! │                                                │                     │
//! │                                                ▼                     │
//! │  ┌────────────────────────────────────────────────────────────────┐ │
//! │  │                    Research Pipeline                           │ │
//! │  │                                                                │ │
//! │  │  ┌───────────┐   ┌─────────────┐   ┌──────────────────────┐   │ │
//! │  │  │ Web       │──▶│ Content     │──▶│ Quality              │   │ │
//! │  │  │ Fetcher   │   │ Extractor   │   │ Validator            │   │ │
//! │  │  └───────────┘   └─────────────┘   └──────────────────────┘   │ │
//! │  │                                                │              │ │
//! │  │                                                ▼              │ │
//! │  │                                    ┌──────────────────────┐   │ │
//! │  │                                    │ Corpus Ingestion     │   │ │
//! │  │                                    │ (if quality passes)  │   │ │
//! │  │                                    └──────────────────────┘   │ │
//! │  └────────────────────────────────────────────────────────────────┘ │
//! └─────────────────────────────────────────────────────────────────────┘
//! ```

mod gap_detector;
mod gap_store;
mod helpers;
mod quality;
mod researcher;

#[cfg(test)]
mod tests;

pub use gap_detector::{detect_gaps, Gap};
pub use gap_store::{GapRecord, GapStore};
pub use quality::{QualityReport, QualityValidator};
pub use researcher::{ResearchConfig, ResearchResult, Researcher};

/// Minimum number of projects that must report a gap before triggering research.
pub const DEFAULT_GAP_THRESHOLD: u32 = 3;

/// Maximum age of a gap (in days) before it's considered stale.
pub const DEFAULT_GAP_MAX_AGE_DAYS: u64 = 90;

/// Confidence threshold for accepting researched claims.
pub const DEFAULT_QUALITY_THRESHOLD: f32 = 0.7;

/// Result of a research operation.
#[derive(Debug)]
pub struct ResearchOutcome {
    /// Number of gaps analyzed.
    pub gaps_analyzed: usize,
    /// Number of gaps successfully researched.
    pub gaps_filled: usize,
    /// Number of assertions created from research.
    pub assertions_created: usize,
    /// Gaps that could not be filled (insufficient quality).
    pub gaps_failed: Vec<String>,
    /// Detailed results per gap.
    pub results: Vec<GapResearchResult>,
}

/// Result of researching a single gap.
#[derive(Debug, Clone)]
pub struct GapResearchResult {
    /// The gap that was researched.
    pub gap: String,
    /// Whether research was successful.
    pub success: bool,
    /// Number of assertions created.
    pub assertions_created: usize,
    /// Quality report for the research.
    pub quality_report: Option<QualityReport>,
    /// Error message if research failed.
    pub error: Option<String>,
}

impl ResearchOutcome {
    /// Create an empty outcome.
    pub fn empty() -> Self {
        Self {
            gaps_analyzed: 0,
            gaps_filled: 0,
            assertions_created: 0,
            gaps_failed: vec![],
            results: vec![],
        }
    }

    /// Check if any research was successful.
    pub fn has_results(&self) -> bool {
        self.assertions_created > 0
    }
}
