#![recursion_limit = "128"]

extern crate proc_macro;

use proc_macro::TokenStream;

use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, quote_spanned, TokenStreamExt};
use syn::spanned::Spanned;
use syn::{
    parse_macro_input, parse_quote, parse_quote_spanned, Error, Expr, ExprLit, ExprPath, ItemFn,
    ItemStruct, Lit, Visibility,
};

macro_rules! err {
    ($span:expr, $message:expr $(,)?) => {
        Error::new($span.span(), $message).to_compile_error()
    };
    ($span:expr, $message:expr, $($args:expr),*) => {
        Error::new($span.span(), format!($message, $($args),*)).to_compile_error()
    };
}

/// Attribute macro for marking structs as UEFI protocols.
///
/// The macro takes one argument, either a GUID string or the path to a `Guid`
/// constant.
///
/// The macro can only be applied to a struct. It implements the
/// [`Protocol`] trait and the `unsafe` [`Identify`] trait for the
/// struct.
///
/// # Safety
///
/// The caller must ensure that the correct GUID is attached to the
/// type. An incorrect GUID could lead to invalid casts and other
/// unsound behavior.
///
/// # Example
///
/// ```
/// use uefi::{Guid, Identify, guid};
/// use uefi::proto::unsafe_protocol;
///
/// #[unsafe_protocol("12345678-9abc-def0-1234-56789abcdef0")]
/// struct ExampleProtocol1 {}
///
/// const PROTO_GUID: Guid = guid!("12345678-9abc-def0-1234-56789abcdef0");
/// #[unsafe_protocol(PROTO_GUID)]
/// struct ExampleProtocol2 {}
///
/// assert_eq!(ExampleProtocol1::GUID, PROTO_GUID);
/// assert_eq!(ExampleProtocol2::GUID, PROTO_GUID);
/// ```
///
/// [`Identify`]: https://docs.rs/uefi/latest/uefi/trait.Identify.html
/// [`Protocol`]: https://docs.rs/uefi/latest/uefi/proto/trait.Protocol.html
/// [send-and-sync]: https://doc.rust-lang.org/nomicon/send-and-sync.html
#[proc_macro_attribute]
pub fn unsafe_protocol(args: TokenStream, input: TokenStream) -> TokenStream {
    let expr = parse_macro_input!(args as Expr);

    let guid_val = match expr {
        Expr::Lit(ExprLit {
            lit: Lit::Str(lit), ..
        }) => {
            quote!(::uefi::guid!(#lit))
        }
        Expr::Path(ExprPath { path, .. }) => quote!(#path),
        _ => {
            return err!(
                expr,
                "macro input must be either a string literal or path to a constant"
            )
            .into()
        }
    };

    let item_struct = parse_macro_input!(input as ItemStruct);

    let ident = &item_struct.ident;
    let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();

    quote! {
        #item_struct

        unsafe impl #impl_generics ::uefi::Identify for #ident #ty_generics #where_clause {
            const GUID: ::uefi::Guid = #guid_val;
        }

        impl #impl_generics ::uefi::proto::Protocol for #ident #ty_generics #where_clause {}
    }
    .into()
}

/// Custom attribute for a UEFI executable entry point.
///
/// This attribute modifies a function to mark it as the entry point for
/// a UEFI executable. The function:
/// * Must return [`Status`].
/// * Must have zero parameters.
/// * Can optionally be `unsafe`.
///
/// The global system table pointer and global image handle will be set
/// automatically.
///
/// # Examples
///
/// ```no_run
/// #![no_main]
///
/// use uefi::prelude::*;
///
/// #[entry]
/// fn main() -> Status {
///     Status::SUCCESS
/// }
/// ```
///
/// [`Status`]: https://docs.rs/uefi/latest/uefi/struct.Status.html
#[proc_macro_attribute]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
    // This code is inspired by the approach in this embedded Rust crate:
    // https://github.com/rust-embedded/cortex-m-rt/blob/965bf1e3291571e7e3b34834864117dc020fb391/macros/src/lib.rs#L85

    let mut errors = TokenStream2::new();

    if !args.is_empty() {
        errors.append_all(err!(
            TokenStream2::from(args),
            "Entry attribute accepts no arguments"
        ));
    }

    let mut f = parse_macro_input!(input as ItemFn);

    if let Some(ref abi) = f.sig.abi {
        errors.append_all(err!(abi, "Entry function must have no ABI modifier"));
    }
    if let Some(asyncness) = f.sig.asyncness {
        errors.append_all(err!(asyncness, "Entry function should not be async"));
    }
    if let Some(constness) = f.sig.constness {
        errors.append_all(err!(constness, "Entry function should not be const"));
    }
    if !f.sig.generics.params.is_empty() {
        errors.append_all(err!(
            f.sig.generics.params,
            "Entry function should not be generic"
        ));
    }
    if !f.sig.inputs.is_empty() {
        errors.append_all(err!(f.sig.inputs, "Entry function must have no arguments"));
    }

    // Show most errors all at once instead of one by one.
    if !errors.is_empty() {
        return errors.into();
    }

    let signature_span = f.sig.span();

    // Fill in the image handle and system table arguments automatically.
    let image_handle_ident = quote!(internal_image_handle);
    let system_table_ident = quote!(internal_system_table);
    f.sig.inputs = parse_quote_spanned!(
        signature_span=>
            #image_handle_ident: ::uefi::Handle,
            #system_table_ident: *const ::core::ffi::c_void,
    );

    // Insert code at the beginning of the entry function to set the global
    // image handle and system table pointer.
    f.block.stmts.insert(
        0,
        parse_quote! {
            unsafe {
                ::uefi::boot::set_image_handle(#image_handle_ident);
                ::uefi::table::set_system_table(#system_table_ident.cast());
            }
        },
    );

    // Set the required ABI.
    f.sig.abi = Some(parse_quote_spanned!(signature_span=> extern "efiapi"));

    // Strip any visibility modifiers.
    f.vis = Visibility::Inherited;

    let unsafety = &f.sig.unsafety;
    let fn_ident = &f.sig.ident;
    let fn_output = &f.sig.output;

    // Get the expected argument types for the main function.
    let expected_args = quote!(::uefi::Handle, *const core::ffi::c_void);

    let fn_type_check = quote_spanned! {signature_span=>
        // Cast from the function type to a function pointer with the same
        // signature first, then try to assign that to an unnamed constant with
        // the desired function pointer type.
        //
        // The cast is used to avoid an "expected fn pointer, found fn item"
        // error if the signature is wrong, since that's not what we are
        // interested in here. Instead we want to tell the user what
        // specifically in the function signature is incorrect.
        const _:
            // The expected fn pointer type.
            #unsafety extern "efiapi" fn(#expected_args) -> ::uefi::Status =
            // Cast from a fn item to a function pointer.
            #fn_ident as #unsafety extern "efiapi" fn(#expected_args) #fn_output;
    };

    let result = quote! {
        #fn_type_check

        #[export_name = "efi_main"]
        #f

    };
    result.into()
}
