// Copyright 2024, Linaro Limited
// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
// SPDX-License-Identifier: GPL-2.0-or-later

use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{quote, quote_spanned};
use syn::{
    parse_macro_input, parse_quote, punctuated::Punctuated, token::Comma, Data, DeriveInput, Field,
    Fields, Ident, Type, Visibility,
};

struct CompileError(String, Span);

impl From<CompileError> for proc_macro2::TokenStream {
    fn from(err: CompileError) -> Self {
        let CompileError(msg, span) = err;
        quote_spanned! { span => compile_error!(#msg); }
    }
}

fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), CompileError> {
    let expected = parse_quote! { #[repr(C)] };

    if input.attrs.iter().any(|attr| attr == &expected) {
        Ok(())
    } else {
        Err(CompileError(
            format!("#[repr(C)] required for {}", msg),
            input.ident.span(),
        ))
    }
}

#[proc_macro_derive(Object)]
pub fn derive_object(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = input.ident;

    let expanded = quote! {
        ::qemu_api::module_init! {
            MODULE_INIT_QOM => unsafe {
                ::qemu_api::bindings::type_register_static(&<#name as ::qemu_api::qom::ObjectImpl>::TYPE_INFO);
            }
        }
    };

    TokenStream::from(expanded)
}

fn get_fields(input: &DeriveInput) -> Result<&Punctuated<Field, Comma>, CompileError> {
    if let Data::Struct(s) = &input.data {
        if let Fields::Named(fs) = &s.fields {
            Ok(&fs.named)
        } else {
            Err(CompileError(
                "Cannot generate offsets for unnamed fields.".to_string(),
                input.ident.span(),
            ))
        }
    } else {
        Err(CompileError(
            "Cannot generate offsets for union or enum.".to_string(),
            input.ident.span(),
        ))
    }
}

#[rustfmt::skip::macros(quote)]
fn derive_offsets_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream, CompileError> {
    is_c_repr(&input, "#[derive(offsets)]")?;

    let name = &input.ident;
    let fields = get_fields(&input)?;
    let field_names: Vec<&Ident> = fields.iter().map(|f| f.ident.as_ref().unwrap()).collect();
    let field_types: Vec<&Type> = fields.iter().map(|f| &f.ty).collect();
    let field_vis: Vec<&Visibility> = fields.iter().map(|f| &f.vis).collect();

    Ok(quote! {
	::qemu_api::with_offsets! {
	    struct #name {
		#(#field_vis #field_names: #field_types,)*
	    }
	}
    })
}

#[proc_macro_derive(offsets)]
pub fn derive_offsets(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let expanded = derive_offsets_or_error(input).unwrap_or_else(Into::into);

    TokenStream::from(expanded)
}
