//! Aphoria - A code-level truth linter powered by Episteme
//!
// Skeleton phase: allow unused code until extractors are implemented
#![allow(dead_code, unused_imports, unused_variables)]
//!
//! Aphoria scans a codebase, extracts the decisions embedded in config and code,
//! and checks them against authoritative sources. It finds the places where what
//! your code *does* contradicts what the specs *say*.
//!
//! # Architecture
//!
//! ```text
//! ┌──────────────────────────────────────────────────────────────┐
//! │                        aphoria CLI                           │
//! │                                                              │
//! │  ┌──────────┐   ┌────────────┐   ┌──────────┐   ┌────────┐  │
//! │  │ Walker   │──▶│ Extractors │──▶│ Ingester │──▶│ Report │  │
//! │  └──────────┘   └────────────┘   └──────────┘   └────────┘  │
//! │                                       │              ▲       │
//! │                                       ▼              │       │
//! │                              ┌──────────────┐        │       │
//! │                              │   Episteme   │────────┘       │
//! │                              │   (local)    │                │
//! │                              └──────────────┘                │
//! └──────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Example
//!
//! ```ignore
//! use aphoria::{run_scan, AphoriaConfig, ScanArgs};
//!
//! let args = ScanArgs {
//!     path: ".".into(),
//!     format: "table".to_string(),
//!     exit_code_enabled: false,
//! };
//! let config = AphoriaConfig::default();
//! let result = run_scan(args, &config).await?;
//!
//! println!("{}", result.display());
//! ```

// Module declarations
mod config;
mod error;
mod extractors;
mod report;
mod types;
mod walker;

// Public re-exports
pub use config::AphoriaConfig;
pub use error::AphoriaError;
pub use types::{AcknowledgeArgs, ConflictResult, ExtractedClaim, ScanArgs, ScanResult, Verdict};

/// Run a scan on the specified project.
///
/// This is the main entry point for scanning a codebase. It:
/// 1. Walks the project directory
/// 2. Extracts claims from config and code
/// 3. Ingests claims into the local Episteme instance
/// 4. Queries for conflicts against authoritative sources
/// 5. Returns a formatted report
pub async fn run_scan(args: ScanArgs, config: &AphoriaConfig) -> Result<ScanResult, AphoriaError> {
    tracing::info!(path = %args.path.display(), format = %args.format, "Starting scan");

    // TODO: Implement full scan pipeline
    // For now, return a stub result to validate the CLI works
    Ok(ScanResult::stub(&args.path, &args.format))
}

/// Acknowledge a conflict as intentional.
///
/// Creates an assertion in Episteme recording that this conflict has been
/// reviewed and accepted. The conflict still appears in reports but marked as ACK.
pub async fn acknowledge(
    args: AcknowledgeArgs,
    _config: &AphoriaConfig,
) -> Result<(), AphoriaError> {
    tracing::info!(
        concept_path = %args.concept_path,
        reason = %args.reason,
        "Acknowledging conflict"
    );

    // TODO: Create acknowledgment assertion in Episteme
    Ok(())
}

/// Set the current scan as the baseline.
///
/// Future `aphoria diff` commands will compare against this baseline.
pub async fn set_baseline(_config: &AphoriaConfig) -> Result<(), AphoriaError> {
    tracing::info!("Setting baseline");

    // TODO: Record baseline scan ID
    Ok(())
}

/// Show changes since the last baseline.
pub async fn show_diff(_config: &AphoriaConfig) -> Result<String, AphoriaError> {
    tracing::info!("Showing diff");

    // TODO: Compare current scan against baseline
    Ok("No baseline set. Run `aphoria baseline` first.".to_string())
}

/// Show current scan status.
pub async fn show_status(_config: &AphoriaConfig) -> Result<String, AphoriaError> {
    tracing::info!("Showing status");

    // TODO: Show summary of local Episteme instance
    Ok("Aphoria status: Not initialized. Run `aphoria init` first.".to_string())
}

/// Initialize Aphoria with the authoritative corpus.
///
/// Downloads and ingests:
/// - RFC corpus (auth, crypto, TLS)
/// - OWASP cheat sheets
pub async fn initialize(_config: &AphoriaConfig) -> Result<(), AphoriaError> {
    tracing::info!("Initializing Aphoria");

    // TODO: Download and ingest authoritative corpus
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::path::PathBuf;

    #[tokio::test]
    async fn test_scan_returns_stub_result() {
        let args = ScanArgs {
            path: PathBuf::from("."),
            format: "table".to_string(),
            exit_code_enabled: false,
        };
        let config = AphoriaConfig::default();

        let result = run_scan(args, &config).await;
        assert!(result.is_ok());

        let scan_result = result.expect("should have result");
        assert!(!scan_result.has_blocks());
    }

    #[tokio::test]
    async fn test_acknowledge_succeeds() {
        let args = AcknowledgeArgs {
            concept_path: "code://rust/test/jwt/audience_validation".to_string(),
            reason: "Internal service".to_string(),
        };
        let config = AphoriaConfig::default();

        let result = acknowledge(args, &config).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_status_before_init() {
        let config = AphoriaConfig::default();
        let result = show_status(&config).await;

        assert!(result.is_ok());
        assert!(result.expect("should have status").contains("Not initialized"));
    }
}
