pub mod simple;

/// Build an in-memory graph lazily at runtime
///
/// # Example
///
/// ```
/// use taganak_framework::lazy_graph;
/// use crate::taganak_framework::prelude::{Graph, GraphView};
/// use futures::StreamExt;
///
/// lazy_graph!(graph, r##"
/// @prefix foo: <https://example.com/foo#> .
/// @prefix rdfs: <https://www.w3.org/2000/01/rdf-schema#> .
///
/// foo:Emil a foo:Turtle ;
///   foo:age 12 ;
///   foo:shell [ foo:color "#00ff00" ; foo:tiles 15 ] .
///
/// foo:Turtle rdfs:label "Schildkröte"@de , "tortoise"@fr .
/// "##
/// );
///
/// tokio_test::block_on(async {
///     let mut stream = graph.view().await.stream().await.unwrap();
///
///     assert_eq!(stream.count().await, 7);
/// });
/// ```
#[cfg(feature = "source_turtle")]
#[macro_export]
macro_rules! lazy_graph {
    ($vis:vis mut $name:ident, $text:expr, $iri:expr) => {
        $vis static $name: ::std::sync::LazyLock<::std::sync::Mutex<$crate::graphs::local::memory::simple::SimpleGraph>> =
            ::std::sync::LazyLock::new(|| {
                let __taganak_reserved_text = $text;
                let mut __taganak_reserved_profile =
                ::taganak_core::environment::profile::BasicProfile::new();
                use ::taganak_core::environment::profile::Profile as _;
                if let Some(__taganak_reserved_iri) = $iri {
                    __taganak_reserved_profile.set_base_iri(
                        Some(::taganak_core::terms::Iri::new(__taganak_reserved_iri.to_string()).unwrap())
                    );
                }
                let mut __taganak_reserved_graph =
                    $crate::graphs::local::memory::simple::SimpleGraph::default();
                let mut __taganak_reserved_parser =
                    ::taganak_core::sources::parsers::turtle::TurtleParser::new_sync(
                        __taganak_reserved_text.as_bytes(),
                        ::std::sync::Arc::new(::std::sync::Mutex::new(
                            __taganak_reserved_profile,
                        )),
                    );

                for __taganak_reserved_triple in __taganak_reserved_parser {
                    let __taganak_reserved_triple = __taganak_reserved_triple.unwrap();
                    __taganak_reserved_graph.add_sync(__taganak_reserved_triple)
                }
                ::std::sync::Mutex::new(__taganak_reserved_graph)
            });
    };
    ($vis:vis $name:ident, $text:expr, $iri:expr) => {
        $vis static $name: ::std::sync::LazyLock<$crate::graphs::local::memory::simple::SimpleGraph> =
            ::std::sync::LazyLock::new(|| {
                let __taganak_reserved_text = $text;
                let mut __taganak_reserved_profile =
                    ::taganak_core::environment::profile::BasicProfile::new();
                use ::taganak_core::environment::profile::Profile as _;
                if let Some(__taganak_reserved_iri) = $iri {
                    __taganak_reserved_profile.set_base_iri(Some(
                        ::taganak_core::terms::Iri::new(__taganak_reserved_iri.to_string()).unwrap())
                    );
                }
                let mut __taganak_reserved_graph =
                    $crate::graphs::local::memory::simple::SimpleGraph::default();
                let mut __taganak_reserved_parser =
                    ::taganak_core::sources::parsers::turtle::TurtleParser::new_sync(
                        __taganak_reserved_text.as_bytes(),
                        ::std::sync::Arc::new(::std::sync::Mutex::new(
                            __taganak_reserved_profile,
                        )),
                    );

                for __taganak_reserved_triple in __taganak_reserved_parser {
                    let __taganak_reserved_triple = __taganak_reserved_triple.unwrap();
                    __taganak_reserved_graph.add_sync(__taganak_reserved_triple)
                }
                __taganak_reserved_graph
            });
    };
    ($vis:vis mut $name:ident, $text:expr) => {
        lazy_graph!($vis mut $name, $text, None as Option<&str>);
    };
    ($vis:vis $name:ident, $text:expr) => {
        lazy_graph!($vis $name, $text, None as Option<&str>);
    };
}

/// Build a term lazily at runtime
///
/// # Example
///
/// ```
/// use taganak_framework::lazy_term;
///
/// lazy_term!(iri_term, "<https://example.com/test_iri>");
///
/// assert_eq!(iri_term.to_string(), "<https://example.com/test_iri>");
/// ```
#[cfg(feature = "source_n_triples")]
#[macro_export]
macro_rules! lazy_term {
    ($vis:vis $name:ident, $text:literal) => {
        $vis static $name: ::std::sync::LazyLock<::std::sync::Arc<taganak_core::terms::Term>> =
            ::std::sync::LazyLock::new(|| ::std::sync::Arc::new($text.try_into().unwrap()));
    };
}

/// Build a triple lazily at runtime
///
/// # Example
///
/// ```
/// use taganak_framework::lazy_triple;
///
/// lazy_triple!(t, "<https://example.com/test_iri> <urn:x-example:size> \"12\"^^<http://www.w3.org/2001/XMLSchema#byte> .");
///
/// assert_eq!(t.subject().to_string(), "<https://example.com/test_iri>");
/// assert_eq!(t.predicate().to_string(), "<urn:x-example:size>");
/// assert_eq!(t.object().clone().into_literal().unwrap(), 12i8.try_into().unwrap());
/// ```
#[cfg(feature = "source_n_triples")]
#[macro_export]
macro_rules! lazy_triple {
    ($vis:vis $name:ident, $text:literal) => {
        $vis static $name: ::std::sync::LazyLock<::std::sync::Arc<::taganak_core::triples::Triple>> =
            ::std::sync::LazyLock::new(|| ::std::sync::Arc::new($text.try_into().unwrap()));
    };
}
