//! Tooling for writing RDF Test Cases Implementation Reports
//!
//! [RDF Test Cases](https://www.w3.org/TR/rdf-testcases/) provide a vocabulary
//! for writing out implementation reports that uses the [EARL](https://www.w3.org/2001/03/earl/)
//! Evaluation And Report Language.
//!
//! This module provides tooling that allows writing out such test reports to
//! a file after running the RDF test suite.

use taganak_framework::{
    graphs::local::persistent::local_file::{LocalFileSourceGraph, LocalFileSourceGraphConfig},
    prelude::*,
};

use iref::IriBuf;
use taganak_framework::{lazy_graph, SELF_TTL};
use taganak_orm::{GraphORM, GraphORMError};

lazy_graph!(mut EARL_GRAPH, SELF_TTL, Some("https://sdk.taganak.net/#"));

#[derive(Debug, PartialEq, GraphORM)]
#[rdf(
    prefix(ns = "earl", iri = "http://www.w3.org/ns/earl#"),
    default(prefix = "earl")
)]
pub(crate) enum OutcomeValue {
    #[rdf(rdf_type = "earl:passed")]
    Passed,
    #[rdf(rdf_type = "earl:failed")]
    Failed,
    #[rdf(rdf_type = "earl:cantTell")]
    CantTell,
    #[rdf(rdf_type = "earl:inapplicable")]
    Inapplicable,
    #[rdf(rdf_type = "earl:untested")]
    Untested,
}

#[derive(Debug, PartialEq, GraphORM)]
#[rdf(
    prefix(ns = "earl", iri = "http://www.w3.org/ns/earl#"),
    default(prefix = "earl", case_conv = true)
)]
pub(crate) struct TestResult {
    pub outcome: OutcomeValue,
}

#[derive(Debug, PartialEq, GraphORM)]
#[rdf(
    prefix(ns = "earl", iri = "http://www.w3.org/ns/earl#"),
    default(prefix = "earl", case_conv = true)
)]
pub(crate) struct Assertion {
    pub subject: Arc<Term>,
    pub test: Arc<Term>,
    pub result: TestResult,
}

impl Assertion {
    pub(crate) fn record(self) -> Result<(), GraphORMError> {
        let rt = tokio::runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .unwrap();

        rt.block_on(async move {
            self.into_meta()
                .serialize(&mut *EARL_GRAPH.lock().unwrap())
                .await
        })
    }
}

/// Write out a finalised EARL graph to a file under a path
pub(crate) fn write_earl_file(path: &str) -> Result<(), GraphError> {
    let path = std::path::absolute(path).unwrap();
    let iri = IriBuf::new(format!("file://{}", path.to_str().unwrap())).unwrap();

    let mut target = LocalFileSourceGraph::from_config(LocalFileSourceGraphConfig::new(
        iri,
        Some(IriBuf::new("https://sdk.taganak.net/#".to_string()).expect("static IRI")),
        None,
        false,
    ))?;

    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(async move { target.merge(EARL_GRAPH.lock().unwrap().view().await).await })
}
