use crate::fragment::{Fragment, Match, Stmts};
use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
use crate::{bound, dummy, pretend, this};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned};
use syn::spanned::Spanned;
use syn::{parse_quote, Ident, Index, Member};

pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<TokenStream> {
    replace_receiver(input);

    let ctxt = Ctxt::new();
    let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
        Some(cont) => cont,
        None => return Err(ctxt.check().unwrap_err()),
    };
    precondition(&ctxt, &cont);
    ctxt.check()?;

    let ident = &cont.ident;
    let params = Parameters::new(&cont);
    let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
    let body = Stmts(serialize_body(&cont, &params));
    let serde = cont.attrs.serde_path();

    let impl_block = if let Some(remote) = cont.attrs.remote() {
        let vis = &input.vis;
        let used = pretend::pretend_used(&cont, params.is_packed);
        quote! {
            impl #impl_generics #ident #ty_generics #where_clause {
                #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
                where
                    __S: #serde::Serializer,
                {
                    #used
                    #body
                }
            }
        }
    } else {
        quote! {
            #[automatically_derived]
            impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause {
                fn serialize<__S>(&self, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
                where
                    __S: #serde::Serializer,
                {
                    #body
                }
            }
        }
    };

    Ok(dummy::wrap_in_const(
        cont.attrs.custom_serde_path(),
        impl_block,
    ))
}

fn precondition(cx: &Ctxt, cont: &Container) {
    match cont.attrs.identifier() {
        attr::Identifier::No => {}
        attr::Identifier::Field => {
            cx.error_spanned_by(cont.original, "field identifiers cannot be serialized");
        }
        attr::Identifier::Variant => {
            cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized");
        }
    }
}

struct Parameters {
    /// Variable holding the value being serialized. Either `self` for local
    /// types or `__self` for remote types.
    self_var: Ident,

    /// Path to the type the impl is for. Either a single `Ident` for local
    /// types (does not include generic parameters) or `some::remote::Path` for
    /// remote types.
    this_type: syn::Path,

    /// Same as `this_type` but using `::<T>` for generic parameters for use in
    /// expression position.
    this_value: syn::Path,

    /// Generics including any explicit and inferred bounds for the impl.
    generics: syn::Generics,

    /// Type has a `serde(remote = "...")` attribute.
    is_remote: bool,

    /// Type has a repr(packed) attribute.
    is_packed: bool,
}

impl Parameters {
    fn new(cont: &Container) -> Self {
        let is_remote = cont.attrs.remote().is_some();
        let self_var = if is_remote {
            Ident::new("__self", Span::call_site())
        } else {
            Ident::new("self", Span::call_site())
        };

        let this_type = this::this_type(cont);
        let this_value = this::this_value(cont);
        let is_packed = cont.attrs.is_packed();
        let generics = build_generics(cont);

        Parameters {
            self_var,
            this_type,
            this_value,
            generics,
            is_remote,
            is_packed,
        }
    }

    /// Type name to use in error messages and `&'static str` arguments to
    /// various Serializer methods.
    fn type_name(&self) -> String {
        self.this_type.segments.last().unwrap().ident.to_string()
    }
}

// All the generics in the input, plus a bound `T: Serialize` for each generic
// field type that will be serialized by us.
fn build_generics(cont: &Container) -> syn::Generics {
    let generics = bound::without_defaults(cont.generics);

    let generics =
        bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound);

    let generics =
        bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::ser_bound);

    match cont.attrs.ser_bound() {
        Some(predicates) => bound::with_where_predicates(&generics, predicates),
        None => bound::with_bound(
            cont,
            &generics,
            needs_serialize_bound,
            &parse_quote!(_serde::Serialize),
        ),
    }
}

// Fields with a `skip_serializing` or `serialize_with` attribute, or which
// belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
// are not serialized by us so we do not generate a bound. Fields with a `bound`
// attribute specify their own bound so we do not generate one. All other fields
// may need a `T: Serialize` bound where T is the type of the field.
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
    !field.skip_serializing()
        && field.serialize_with().is_none()
        && field.ser_bound().is_none()
        && variant.map_or(true, |variant| {
            !variant.skip_serializing()
                && variant.serialize_with().is_none()
                && variant.ser_bound().is_none()
        })
}

fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
    if cont.attrs.transparent() {
        serialize_transparent(cont, params)
    } else if let Some(type_into) = cont.attrs.type_into() {
        serialize_into(params, type_into)
    } else {
        match &cont.data {
            Data::Enum(variants) => serialize_enum(params, variants, &cont.attrs),
            Data::Struct(Style::Struct, fields) => serialize_struct(params, fields, &cont.attrs),
            Data::Struct(Style::Tuple, fields) => {
                serialize_tuple_struct(params, fields, &cont.attrs)
            }
            Data::Struct(Style::Newtype, fields) => {
                serialize_newtype_struct(params, &fields[0], &cont.attrs)
            }
            Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
        }
    }
}

fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
    let fields = match &cont.data {
        Data::Struct(_, fields) => fields,
        Data::Enum(_) => unreachable!(),
    };

    let self_var = &params.self_var;
    let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
    let member = &transparent_field.member;

    let path = match transparent_field.attrs.serialize_with() {
        Some(path) => quote!(#path),
        None => {
            let span = transparent_field.original.span();
            quote_spanned!(span=> _serde::Serialize::serialize)
        }
    };

    quote_block! {
        #path(&#self_var.#member, __serializer)
    }
}

fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
    let self_var = &params.self_var;
    quote_block! {
        _serde::Serialize::serialize(
            &_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)),
            __serializer)
    }
}

fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment {
    let type_name = cattrs.name().serialize_name();

    quote_expr! {
        _serde::Serializer::serialize_unit_struct(__serializer, #type_name)
    }
}

fn serialize_newtype_struct(
    params: &Parameters,
    field: &Field,
    cattrs: &attr::Container,
) -> Fragment {
    let type_name = cattrs.name().serialize_name();

    let mut field_expr = get_member(
        params,
        field,
        &Member::Unnamed(Index {
            index: 0,
            span: Span::call_site(),
        }),
    );
    if let Some(path) = field.attrs.serialize_with() {
        field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
    }

    let span = field.original.span();
    let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct);
    quote_expr! {
        #func(__serializer, #type_name, #field_expr)
    }
}

fn serialize_tuple_struct(
    params: &Parameters,
    fields: &[Field],
    cattrs: &attr::Container,
) -> Fragment {
    let serialize_stmts =
        serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct);

    let type_name = cattrs.name().serialize_name();

    let mut serialized_fields = fields
        .iter()
        .enumerate()
        .filter(|(_, field)| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some());

    let len = serialized_fields
        .map(|(i, field)| match field.attrs.skip_serializing_if() {
            None => quote!(1),
            Some(path) => {
                let index = syn::Index {
                    index: i as u32,
                    span: Span::call_site(),
                };
                let field_expr = get_member(params, field, &Member::Unnamed(index));
                quote!(if #path(#field_expr) { 0 } else { 1 })
            }
        })
        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));

    quote_block! {
        let #let_mut __serde_state = _serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)?;
        #(#serialize_stmts)*
        _serde::ser::SerializeTupleStruct::end(__serde_state)
    }
}

fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
    assert!(fields.len() as u64 <= u64::from(u32::max_value()));

    if cattrs.has_flatten() {
        serialize_struct_as_map(params, fields, cattrs)
    } else {
        serialize_struct_as_struct(params, fields, cattrs)
    }
}

fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream {
    match cattrs.tag() {
        attr::TagType::Internal { tag } => {
            let type_name = cattrs.name().serialize_name();
            let func = struct_trait.serialize_field(Span::call_site());
            quote! {
                #func(&mut __serde_state, #tag, #type_name)?;
            }
        }
        _ => quote! {},
    }
}

fn serialize_struct_as_struct(
    params: &Parameters,
    fields: &[Field],
    cattrs: &attr::Container,
) -> Fragment {
    let serialize_fields =
        serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct);

    let type_name = cattrs.name().serialize_name();

    let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct);
    let tag_field_exists = !tag_field.is_empty();

    let mut serialized_fields = fields
        .iter()
        .filter(|&field| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);

    let len = serialized_fields
        .map(|field| match field.attrs.skip_serializing_if() {
            None => quote!(1),
            Some(path) => {
                let field_expr = get_member(params, field, &field.member);
                quote!(if #path(#field_expr) { 0 } else { 1 })
            }
        })
        .fold(
            quote!(#tag_field_exists as usize),
            |sum, expr| quote!(#sum + #expr),
        );

    quote_block! {
        let #let_mut __serde_state = _serde::Serializer::serialize_struct(__serializer, #type_name, #len)?;
        #tag_field
        #(#serialize_fields)*
        _serde::ser::SerializeStruct::end(__serde_state)
    }
}

fn serialize_struct_as_map(
    params: &Parameters,
    fields: &[Field],
    cattrs: &attr::Container,
) -> Fragment {
    let serialize_fields =
        serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap);

    let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap);
    let tag_field_exists = !tag_field.is_empty();

    let mut serialized_fields = fields
        .iter()
        .filter(|&field| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);

    let len = if cattrs.has_flatten() {
        quote!(_serde::__private::None)
    } else {
        let len = serialized_fields
            .map(|field| match field.attrs.skip_serializing_if() {
                None => quote!(1),
                Some(path) => {
                    let field_expr = get_member(params, field, &field.member);
                    quote!(if #path(#field_expr) { 0 } else { 1 })
                }
            })
            .fold(
                quote!(#tag_field_exists as usize),
                |sum, expr| quote!(#sum + #expr),
            );
        quote!(_serde::__private::Some(#len))
    };

    quote_block! {
        let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, #len)?;
        #tag_field
        #(#serialize_fields)*
        _serde::ser::SerializeMap::end(__serde_state)
    }
}

fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
    assert!(variants.len() as u64 <= u64::from(u32::max_value()));

    let self_var = &params.self_var;

    let mut arms: Vec<_> = variants
        .iter()
        .enumerate()
        .map(|(variant_index, variant)| {
            serialize_variant(params, variant, variant_index as u32, cattrs)
        })
        .collect();

    if cattrs.remote().is_some() && cattrs.non_exhaustive() {
        arms.push(quote! {
            ref unrecognized => _serde::__private::Err(_serde::ser::Error::custom(_serde::__private::ser::CannotSerializeVariant(unrecognized))),
        });
    }

    quote_expr! {
        match *#self_var {
            #(#arms)*
        }
    }
}

fn serialize_variant(
    params: &Parameters,
    variant: &Variant,
    variant_index: u32,
    cattrs: &attr::Container,
) -> TokenStream {
    let this_value = &params.this_value;
    let variant_ident = &variant.ident;

    if variant.attrs.skip_serializing() {
        let skipped_msg = format!(
            "the enum variant {}::{} cannot be serialized",
            params.type_name(),
            variant_ident
        );
        let skipped_err = quote! {
            _serde::__private::Err(_serde::ser::Error::custom(#skipped_msg))
        };
        let fields_pat = match variant.style {
            Style::Unit => quote!(),
            Style::Newtype | Style::Tuple => quote!((..)),
            Style::Struct => quote!({ .. }),
        };
        quote! {
            #this_value::#variant_ident #fields_pat => #skipped_err,
        }
    } else {
        // variant wasn't skipped
        let case = match variant.style {
            Style::Unit => {
                quote! {
                    #this_value::#variant_ident
                }
            }
            Style::Newtype => {
                quote! {
                    #this_value::#variant_ident(ref __field0)
                }
            }
            Style::Tuple => {
                let field_names = (0..variant.fields.len())
                    .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
                quote! {
                    #this_value::#variant_ident(#(ref #field_names),*)
                }
            }
            Style::Struct => {
                let members = variant.fields.iter().map(|f| &f.member);
                quote! {
                    #this_value::#variant_ident { #(ref #members),* }
                }
            }
        };

        let body = Match(match (cattrs.tag(), variant.attrs.untagged()) {
            (attr::TagType::External, false) => {
                serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
            }
            (attr::TagType::Internal { tag }, false) => {
                serialize_internally_tagged_variant(params, variant, cattrs, tag)
            }
            (attr::TagType::Adjacent { tag, content }, false) => {
                serialize_adjacently_tagged_variant(
                    params,
                    variant,
                    cattrs,
                    variant_index,
                    tag,
                    content,
                )
            }
            (attr::TagType::None, _) | (_, true) => {
                serialize_untagged_variant(params, variant, cattrs)
            }
        });

        quote! {
            #case => #body
        }
    }
}

fn serialize_externally_tagged_variant(
    params: &Parameters,
    variant: &Variant,
    variant_index: u32,
    cattrs: &attr::Container,
) -> Fragment {
    let type_name = cattrs.name().serialize_name();
    let variant_name = variant.attrs.name().serialize_name();

    if let Some(path) = variant.attrs.serialize_with() {
        let ser = wrap_serialize_variant_with(params, path, variant);
        return quote_expr! {
            _serde::Serializer::serialize_newtype_variant(
                __serializer,
                #type_name,
                #variant_index,
                #variant_name,
                #ser,
            )
        };
    }

    match effective_style(variant) {
        Style::Unit => {
            quote_expr! {
                _serde::Serializer::serialize_unit_variant(
                    __serializer,
                    #type_name,
                    #variant_index,
                    #variant_name,
                )
            }
        }
        Style::Newtype => {
            let field = &variant.fields[0];
            let mut field_expr = quote!(__field0);
            if let Some(path) = field.attrs.serialize_with() {
                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
            }

            let span = field.original.span();
            let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant);
            quote_expr! {
                #func(
                    __serializer,
                    #type_name,
                    #variant_index,
                    #variant_name,
                    #field_expr,
                )
            }
        }
        Style::Tuple => serialize_tuple_variant(
            TupleVariant::ExternallyTagged {
                type_name,
                variant_index,
                variant_name,
            },
            params,
            &variant.fields,
        ),
        Style::Struct => serialize_struct_variant(
            StructVariant::ExternallyTagged {
                variant_index,
                variant_name,
            },
            params,
            &variant.fields,
            type_name,
        ),
    }
}

fn serialize_internally_tagged_variant(
    params: &Parameters,
    variant: &Variant,
    cattrs: &attr::Container,
    tag: &str,
) -> Fragment {
    let type_name = cattrs.name().serialize_name();
    let variant_name = variant.attrs.name().serialize_name();

    let enum_ident_str = params.type_name();
    let variant_ident_str = variant.ident.to_string();

    if let Some(path) = variant.attrs.serialize_with() {
        let ser = wrap_serialize_variant_with(params, path, variant);
        return quote_expr! {
            _serde::__private::ser::serialize_tagged_newtype(
                __serializer,
                #enum_ident_str,
                #variant_ident_str,
                #tag,
                #variant_name,
                #ser,
            )
        };
    }

    match effective_style(variant) {
        Style::Unit => {
            quote_block! {
                let mut __struct = _serde::Serializer::serialize_struct(
                    __serializer, #type_name, 1)?;
                _serde::ser::SerializeStruct::serialize_field(
                    &mut __struct, #tag, #variant_name)?;
                _serde::ser::SerializeStruct::end(__struct)
            }
        }
        Style::Newtype => {
            let field = &variant.fields[0];
            let mut field_expr = quote!(__field0);
            if let Some(path) = field.attrs.serialize_with() {
                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
            }

            let span = field.original.span();
            let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype);
            quote_expr! {
                #func(
                    __serializer,
                    #enum_ident_str,
                    #variant_ident_str,
                    #tag,
                    #variant_name,
                    #field_expr,
                )
            }
        }
        Style::Struct => serialize_struct_variant(
            StructVariant::InternallyTagged { tag, variant_name },
            params,
            &variant.fields,
            type_name,
        ),
        Style::Tuple => unreachable!("checked in serde_derive_internals"),
    }
}

fn serialize_adjacently_tagged_variant(
    params: &Parameters,
    variant: &Variant,
    cattrs: &attr::Container,
    variant_index: u32,
    tag: &str,
    content: &str,
) -> Fragment {
    let this_type = &params.this_type;
    let type_name = cattrs.name().serialize_name();
    let variant_name = variant.attrs.name().serialize_name();
    let serialize_variant = quote! {
        &_serde::__private::ser::AdjacentlyTaggedEnumVariant {
            enum_name: #type_name,
            variant_index: #variant_index,
            variant_name: #variant_name,
        }
    };

    let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
        let ser = wrap_serialize_variant_with(params, path, variant);
        quote_expr! {
            _serde::Serialize::serialize(#ser, __serializer)
        }
    } else {
        match effective_style(variant) {
            Style::Unit => {
                return quote_block! {
                    let mut __struct = _serde::Serializer::serialize_struct(
                        __serializer, #type_name, 1)?;
                    _serde::ser::SerializeStruct::serialize_field(
                        &mut __struct, #tag, #serialize_variant)?;
                    _serde::ser::SerializeStruct::end(__struct)
                };
            }
            Style::Newtype => {
                let field = &variant.fields[0];
                let mut field_expr = quote!(__field0);
                if let Some(path) = field.attrs.serialize_with() {
                    field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
                }

                let span = field.original.span();
                let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field);
                return quote_block! {
                    let mut __struct = _serde::Serializer::serialize_struct(
                        __serializer, #type_name, 2)?;
                    _serde::ser::SerializeStruct::serialize_field(
                        &mut __struct, #tag, #serialize_variant)?;
                    #func(
                        &mut __struct, #content, #field_expr)?;
                    _serde::ser::SerializeStruct::end(__struct)
                };
            }
            Style::Tuple => {
                serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
            }
            Style::Struct => serialize_struct_variant(
                StructVariant::Untagged,
                params,
                &variant.fields,
                variant_name,
            ),
        }
    });

    let fields_ty = variant.fields.iter().map(|f| &f.ty);
    let fields_ident: &[_] = &match variant.style {
        Style::Unit => {
            if variant.attrs.serialize_with().is_some() {
                vec![]
            } else {
                unreachable!()
            }
        }
        Style::Newtype => vec![Member::Named(Ident::new("__field0", Span::call_site()))],
        Style::Tuple => (0..variant.fields.len())
            .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site())))
            .collect(),
        Style::Struct => variant.fields.iter().map(|f| f.member.clone()).collect(),
    };

    let (_, ty_generics, where_clause) = params.generics.split_for_impl();

    let wrapper_generics = if fields_ident.is_empty() {
        params.generics.clone()
    } else {
        bound::with_lifetime_bound(&params.generics, "'__a")
    };
    let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();

    quote_block! {
        #[doc(hidden)]
        struct __AdjacentlyTagged #wrapper_generics #where_clause {
            data: (#(&'__a #fields_ty,)*),
            phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
        }

        impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
            fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
            where
                __S: _serde::Serializer,
            {
                // Elements that have skip_serializing will be unused.
                #[allow(unused_variables)]
                let (#(#fields_ident,)*) = self.data;
                #inner
            }
        }

        let mut __struct = _serde::Serializer::serialize_struct(
            __serializer, #type_name, 2)?;
        _serde::ser::SerializeStruct::serialize_field(
            &mut __struct, #tag, #serialize_variant)?;
        _serde::ser::SerializeStruct::serialize_field(
            &mut __struct, #content, &__AdjacentlyTagged {
                data: (#(#fields_ident,)*),
                phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
            })?;
        _serde::ser::SerializeStruct::end(__struct)
    }
}

fn serialize_untagged_variant(
    params: &Parameters,
    variant: &Variant,
    cattrs: &attr::Container,
) -> Fragment {
    if let Some(path) = variant.attrs.serialize_with() {
        let ser = wrap_serialize_variant_with(params, path, variant);
        return quote_expr! {
            _serde::Serialize::serialize(#ser, __serializer)
        };
    }

    match effective_style(variant) {
        Style::Unit => {
            quote_expr! {
                _serde::Serializer::serialize_unit(__serializer)
            }
        }
        Style::Newtype => {
            let field = &variant.fields[0];
            let mut field_expr = quote!(__field0);
            if let Some(path) = field.attrs.serialize_with() {
                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
            }

            let span = field.original.span();
            let func = quote_spanned!(span=> _serde::Serialize::serialize);
            quote_expr! {
                #func(#field_expr, __serializer)
            }
        }
        Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
        Style::Struct => {
            let type_name = cattrs.name().serialize_name();
            serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, type_name)
        }
    }
}

enum TupleVariant<'a> {
    ExternallyTagged {
        type_name: &'a str,
        variant_index: u32,
        variant_name: &'a str,
    },
    Untagged,
}

fn serialize_tuple_variant(
    context: TupleVariant,
    params: &Parameters,
    fields: &[Field],
) -> Fragment {
    let tuple_trait = match context {
        TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant,
        TupleVariant::Untagged => TupleTrait::SerializeTuple,
    };

    let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);

    let mut serialized_fields = fields
        .iter()
        .enumerate()
        .filter(|(_, field)| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some());

    let len = serialized_fields
        .map(|(i, field)| match field.attrs.skip_serializing_if() {
            None => quote!(1),
            Some(path) => {
                let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
                quote!(if #path(#field_expr) { 0 } else { 1 })
            }
        })
        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));

    match context {
        TupleVariant::ExternallyTagged {
            type_name,
            variant_index,
            variant_name,
        } => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_tuple_variant(
                    __serializer,
                    #type_name,
                    #variant_index,
                    #variant_name,
                    #len)?;
                #(#serialize_stmts)*
                _serde::ser::SerializeTupleVariant::end(__serde_state)
            }
        }
        TupleVariant::Untagged => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_tuple(
                    __serializer,
                    #len)?;
                #(#serialize_stmts)*
                _serde::ser::SerializeTuple::end(__serde_state)
            }
        }
    }
}

enum StructVariant<'a> {
    ExternallyTagged {
        variant_index: u32,
        variant_name: &'a str,
    },
    InternallyTagged {
        tag: &'a str,
        variant_name: &'a str,
    },
    Untagged,
}

fn serialize_struct_variant(
    context: StructVariant,
    params: &Parameters,
    fields: &[Field],
    name: &str,
) -> Fragment {
    if fields.iter().any(|field| field.attrs.flatten()) {
        return serialize_struct_variant_with_flatten(context, params, fields, name);
    }

    let struct_trait = match context {
        StructVariant::ExternallyTagged { .. } => StructTrait::SerializeStructVariant,
        StructVariant::InternallyTagged { .. } | StructVariant::Untagged => {
            StructTrait::SerializeStruct
        }
    };

    let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);

    let mut serialized_fields = fields
        .iter()
        .filter(|&field| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some());

    let len = serialized_fields
        .map(|field| {
            let member = &field.member;

            match field.attrs.skip_serializing_if() {
                Some(path) => quote!(if #path(#member) { 0 } else { 1 }),
                None => quote!(1),
            }
        })
        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));

    match context {
        StructVariant::ExternallyTagged {
            variant_index,
            variant_name,
        } => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_struct_variant(
                    __serializer,
                    #name,
                    #variant_index,
                    #variant_name,
                    #len,
                )?;
                #(#serialize_fields)*
                _serde::ser::SerializeStructVariant::end(__serde_state)
            }
        }
        StructVariant::InternallyTagged { tag, variant_name } => {
            quote_block! {
                let mut __serde_state = _serde::Serializer::serialize_struct(
                    __serializer,
                    #name,
                    #len + 1,
                )?;
                _serde::ser::SerializeStruct::serialize_field(
                    &mut __serde_state,
                    #tag,
                    #variant_name,
                )?;
                #(#serialize_fields)*
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
        StructVariant::Untagged => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_struct(
                    __serializer,
                    #name,
                    #len,
                )?;
                #(#serialize_fields)*
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    }
}

fn serialize_struct_variant_with_flatten(
    context: StructVariant,
    params: &Parameters,
    fields: &[Field],
    name: &str,
) -> Fragment {
    let struct_trait = StructTrait::SerializeMap;
    let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);

    let mut serialized_fields = fields
        .iter()
        .filter(|&field| !field.attrs.skip_serializing())
        .peekable();

    let let_mut = mut_if(serialized_fields.peek().is_some());

    match context {
        StructVariant::ExternallyTagged {
            variant_index,
            variant_name,
        } => {
            let this_type = &params.this_type;
            let fields_ty = fields.iter().map(|f| &f.ty);
            let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();

            let (_, ty_generics, where_clause) = params.generics.split_for_impl();
            let wrapper_generics = bound::with_lifetime_bound(&params.generics, "'__a");
            let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();

            quote_block! {
                #[doc(hidden)]
                struct __EnumFlatten #wrapper_generics #where_clause {
                    data: (#(&'__a #fields_ty,)*),
                    phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
                }

                impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
                    fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
                    where
                        __S: _serde::Serializer,
                    {
                        let (#(#members,)*) = self.data;
                        let #let_mut __serde_state = _serde::Serializer::serialize_map(
                            __serializer,
                            _serde::__private::None)?;
                        #(#serialize_fields)*
                        _serde::ser::SerializeMap::end(__serde_state)
                    }
                }

                _serde::Serializer::serialize_newtype_variant(
                    __serializer,
                    #name,
                    #variant_index,
                    #variant_name,
                    &__EnumFlatten {
                        data: (#(#members,)*),
                        phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
                    })
            }
        }
        StructVariant::InternallyTagged { tag, variant_name } => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_map(
                    __serializer,
                    _serde::__private::None)?;
                _serde::ser::SerializeMap::serialize_entry(
                    &mut __serde_state,
                    #tag,
                    #variant_name,
                )?;
                #(#serialize_fields)*
                _serde::ser::SerializeMap::end(__serde_state)
            }
        }
        StructVariant::Untagged => {
            quote_block! {
                let #let_mut __serde_state = _serde::Serializer::serialize_map(
                    __serializer,
                    _serde::__private::None)?;
                #(#serialize_fields)*
                _serde::ser::SerializeMap::end(__serde_state)
            }
        }
    }
}

fn serialize_tuple_struct_visitor(
    fields: &[Field],
    params: &Parameters,
    is_enum: bool,
    tuple_trait: &TupleTrait,
) -> Vec<TokenStream> {
    fields
        .iter()
        .enumerate()
        .filter(|(_, field)| !field.attrs.skip_serializing())
        .map(|(i, field)| {
            let mut field_expr = if is_enum {
                let id = Ident::new(&format!("__field{}", i), Span::call_site());
                quote!(#id)
            } else {
                get_member(
                    params,
                    field,
                    &Member::Unnamed(Index {
                        index: i as u32,
                        span: Span::call_site(),
                    }),
                )
            };

            let skip = field
                .attrs
                .skip_serializing_if()
                .map(|path| quote!(#path(#field_expr)));

            if let Some(path) = field.attrs.serialize_with() {
                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
            }

            let span = field.original.span();
            let func = tuple_trait.serialize_element(span);
            let ser = quote! {
                #func(&mut __serde_state, #field_expr)?;
            };

            match skip {
                None => ser,
                Some(skip) => quote!(if !#skip { #ser }),
            }
        })
        .collect()
}

fn serialize_struct_visitor(
    fields: &[Field],
    params: &Parameters,
    is_enum: bool,
    struct_trait: &StructTrait,
) -> Vec<TokenStream> {
    fields
        .iter()
        .filter(|&field| !field.attrs.skip_serializing())
        .map(|field| {
            let member = &field.member;

            let mut field_expr = if is_enum {
                quote!(#member)
            } else {
                get_member(params, field, member)
            };

            let key_expr = field.attrs.name().serialize_name();

            let skip = field
                .attrs
                .skip_serializing_if()
                .map(|path| quote!(#path(#field_expr)));

            if let Some(path) = field.attrs.serialize_with() {
                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
            }

            let span = field.original.span();
            let ser = if field.attrs.flatten() {
                let func = quote_spanned!(span=> _serde::Serialize::serialize);
                quote! {
                    #func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?;
                }
            } else {
                let func = struct_trait.serialize_field(span);
                quote! {
                    #func(&mut __serde_state, #key_expr, #field_expr)?;
                }
            };

            match skip {
                None => ser,
                Some(skip) => {
                    if let Some(skip_func) = struct_trait.skip_field(span) {
                        quote! {
                            if !#skip {
                                #ser
                            } else {
                                #skip_func(&mut __serde_state, #key_expr)?;
                            }
                        }
                    } else {
                        quote! {
                            if !#skip {
                                #ser
                            }
                        }
                    }
                }
            }
        })
        .collect()
}

fn wrap_serialize_field_with(
    params: &Parameters,
    field_ty: &syn::Type,
    serialize_with: &syn::ExprPath,
    field_expr: &TokenStream,
) -> TokenStream {
    wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)])
}

fn wrap_serialize_variant_with(
    params: &Parameters,
    serialize_with: &syn::ExprPath,
    variant: &Variant,
) -> TokenStream {
    let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
    let field_exprs: Vec<_> = variant
        .fields
        .iter()
        .map(|field| {
            let id = match &field.member {
                Member::Named(ident) => ident.clone(),
                Member::Unnamed(member) => {
                    Ident::new(&format!("__field{}", member.index), Span::call_site())
                }
            };
            quote!(#id)
        })
        .collect();
    wrap_serialize_with(
        params,
        serialize_with,
        field_tys.as_slice(),
        field_exprs.as_slice(),
    )
}

fn wrap_serialize_with(
    params: &Parameters,
    serialize_with: &syn::ExprPath,
    field_tys: &[&syn::Type],
    field_exprs: &[TokenStream],
) -> TokenStream {
    let this_type = &params.this_type;
    let (_, ty_generics, where_clause) = params.generics.split_for_impl();

    let wrapper_generics = if field_exprs.is_empty() {
        params.generics.clone()
    } else {
        bound::with_lifetime_bound(&params.generics, "'__a")
    };
    let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();

    let field_access = (0..field_exprs.len()).map(|n| {
        Member::Unnamed(Index {
            index: n as u32,
            span: Span::call_site(),
        })
    });

    quote!({
        #[doc(hidden)]
        struct __SerializeWith #wrapper_impl_generics #where_clause {
            values: (#(&'__a #field_tys, )*),
            phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
        }

        impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
            fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
            where
                __S: _serde::Serializer,
            {
                #serialize_with(#(self.values.#field_access, )* __s)
            }
        }

        &__SerializeWith {
            values: (#(#field_exprs, )*),
            phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
        }
    })
}

// Serialization of an empty struct results in code like:
//
//     let mut __serde_state = serializer.serialize_struct("S", 0)?;
//     _serde::ser::SerializeStruct::end(__serde_state)
//
// where we want to omit the `mut` to avoid a warning.
fn mut_if(is_mut: bool) -> Option<TokenStream> {
    if is_mut {
        Some(quote!(mut))
    } else {
        None
    }
}

fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream {
    let self_var = &params.self_var;
    match (params.is_remote, field.attrs.getter()) {
        (false, None) => {
            if params.is_packed {
                quote!(&{#self_var.#member})
            } else {
                quote!(&#self_var.#member)
            }
        }
        (true, None) => {
            let inner = if params.is_packed {
                quote!(&{#self_var.#member})
            } else {
                quote!(&#self_var.#member)
            };
            let ty = field.ty;
            quote!(_serde::__private::ser::constrain::<#ty>(#inner))
        }
        (true, Some(getter)) => {
            let ty = field.ty;
            quote!(_serde::__private::ser::constrain::<#ty>(&#getter(#self_var)))
        }
        (false, Some(_)) => {
            unreachable!("getter is only allowed for remote impls");
        }
    }
}

fn effective_style(variant: &Variant) -> Style {
    match variant.style {
        Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit,
        other => other,
    }
}

enum StructTrait {
    SerializeMap,
    SerializeStruct,
    SerializeStructVariant,
}

impl StructTrait {
    fn serialize_field(&self, span: Span) -> TokenStream {
        match *self {
            StructTrait::SerializeMap => {
                quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry)
            }
            StructTrait::SerializeStruct => {
                quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field)
            }
            StructTrait::SerializeStructVariant => {
                quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field)
            }
        }
    }

    fn skip_field(&self, span: Span) -> Option<TokenStream> {
        match *self {
            StructTrait::SerializeMap => None,
            StructTrait::SerializeStruct => {
                Some(quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field))
            }
            StructTrait::SerializeStructVariant => {
                Some(quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field))
            }
        }
    }
}

enum TupleTrait {
    SerializeTuple,
    SerializeTupleStruct,
    SerializeTupleVariant,
}

impl TupleTrait {
    fn serialize_element(&self, span: Span) -> TokenStream {
        match *self {
            TupleTrait::SerializeTuple => {
                quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element)
            }
            TupleTrait::SerializeTupleStruct => {
                quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field)
            }
            TupleTrait::SerializeTupleVariant => {
                quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field)
            }
        }
    }
}
