//! Display trait implementation generation

use proc_macro2::TokenStream;
use quote::quote;

use crate::ir::{EnumDefinition, VariantDefinition};

use super::helpers::{build_transparent_pattern, build_variant_pattern};

/// Generate the Display trait implementation
pub fn generate_display_impl(ir: &EnumDefinition) -> TokenStream {
    let name = &ir.name;
    let (impl_generics, ty_generics, where_clause) = ir.generics.split_for_impl();

    let match_arms: Vec<_> = ir
        .variants
        .iter()
        .flat_map(|variant| match variant {
            VariantDefinition::Regular(regular) => {
                let variant_name = &regular.name;
                let message = &regular.error_message;
                let pattern = build_variant_pattern(regular);

                vec![quote! {
                    Self::#variant_name #pattern => write!(__apollo_formatter, #message),
                }]
            }
            VariantDefinition::Transparent(transparent) => {
                let variant_name = &transparent.name;
                let pattern = build_transparent_pattern(transparent);
                vec![quote! {
                    Self::#variant_name #pattern => ::std::fmt::Display::fmt(inner, __apollo_formatter),
                }]
            }
        })
        .collect();

    quote! {
        #[automatically_derived]
        impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause {
            fn fmt(&self, __apollo_formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                match self {
                    #(#match_arms)*
                }
            }
        }
    }
}
