use crate::{
    dependencies::{is_root_arcis, is_root_arcis_library},
    error::{Error, SpanRange},
    helper_cleaner::HelperCleaner,
    interpreter_builder::InterpreterBuilder,
};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};

pub fn library_macro(input: TokenStream) -> TokenStream {
    let mut module = match syn::parse2(input.clone()) {
        Ok(module) => module,
        Err(e) => {
            let mut output = input;
            output.extend(e.to_compile_error());
            return output;
        }
    };
    let interpreter_builder = InterpreterBuilder::new(&module);
    let mut interpreter = interpreter_builder.run();

    if module.ident != "arcis_library" {
        let e = Error::new_spanned(
            &module.ident,
            "In arcis libraries, the (discarded) module name should be \"arcis_library\".",
        );
        interpreter.errors.push(e);
    }
    if !is_root_arcis_library() && !is_root_arcis() {
        let e = Error::new(
            SpanRange::call_site(),
            "To be a arcis library, you also need to put in the library's Cargo.toml:\nkeywords = [\"arcis-library\"]"
        );
        interpreter.errors.push(e);
    }
    let errors = interpreter
        .errors()
        .into_iter()
        .map(|e| e.to_token_stream());
    HelperCleaner::clean(&mut module);
    let content = module.content.unwrap();
    let mod_content = content.1.iter();
    quote! {
        #(#mod_content)*
        #(#errors)*
    }
}
