use crate::syntax::attrs::OtherAttrs;
use crate::syntax::cfg::CfgExpr;
use crate::syntax::discriminant::DiscriminantSet;
use crate::syntax::file::{Item, ItemForeignMod};
use crate::syntax::report::Errors;
use crate::syntax::Atom::*;
use crate::syntax::{
    attrs, error, Api, Array, Derive, Doc, Enum, EnumRepr, ExternFn, ExternType, ForeignName, Impl,
    Include, IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref,
    Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
};
use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned};
use std::mem;
use syn::parse::{ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::{
    Abi, Attribute, Error, Expr, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType,
    GenericArgument, GenericParam, Generics, Ident, ItemEnum, ItemImpl, ItemStruct, Lit, LitStr,
    Pat, PathArguments, Result, ReturnType, Signature as RustSignature, Token, TraitBound,
    TraitBoundModifier, Type as RustType, TypeArray, TypeBareFn, TypeParamBound, TypePath, TypePtr,
    TypeReference, Variant as RustVariant, Visibility,
};

pub(crate) mod kw {
    syn::custom_keyword!(Pin);
    syn::custom_keyword!(Result);
}

pub(crate) fn parse_items(
    cx: &mut Errors,
    items: Vec<Item>,
    trusted: bool,
    namespace: &Namespace,
) -> Vec<Api> {
    let mut apis = Vec::new();
    for item in items {
        match item {
            Item::Struct(item) => match parse_struct(cx, item, namespace) {
                Ok(strct) => apis.push(strct),
                Err(err) => cx.push(err),
            },
            Item::Enum(item) => apis.push(parse_enum(cx, item, namespace)),
            Item::ForeignMod(foreign_mod) => {
                parse_foreign_mod(cx, foreign_mod, &mut apis, trusted, namespace);
            }
            Item::Impl(item) => match parse_impl(cx, item) {
                Ok(imp) => apis.push(imp),
                Err(err) => cx.push(err),
            },
            Item::Use(item) => cx.error(item, error::USE_NOT_ALLOWED),
            Item::Other(item) => cx.error(item, "unsupported item"),
        }
    }
    apis
}

fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {
    let mut cfg = CfgExpr::Unconditional;
    let mut doc = Doc::new();
    let mut derives = Vec::new();
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let attrs = attrs::parse(
        cx,
        mem::take(&mut item.attrs),
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            derives: Some(&mut derives),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    );

    let named_fields = match item.fields {
        Fields::Named(fields) => fields,
        Fields::Unit => return Err(Error::new_spanned(item, "unit structs are not supported")),
        Fields::Unnamed(_) => {
            return Err(Error::new_spanned(item, "tuple structs are not supported"));
        }
    };

    let mut lifetimes = Punctuated::new();
    let mut has_unsupported_generic_param = false;
    for pair in item.generics.params.into_pairs() {
        let (param, punct) = pair.into_tuple();
        match param {
            GenericParam::Lifetime(param) => {
                if !param.bounds.is_empty() && !has_unsupported_generic_param {
                    let msg = "lifetime parameter with bounds is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
                lifetimes.push_value(param.lifetime);
                if let Some(punct) = punct {
                    lifetimes.push_punct(punct);
                }
            }
            GenericParam::Type(param) => {
                if !has_unsupported_generic_param {
                    let msg = "struct with generic type parameter is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
            }
            GenericParam::Const(param) => {
                if !has_unsupported_generic_param {
                    let msg = "struct with const generic parameter is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
            }
        }
    }

    if let Some(where_clause) = &item.generics.where_clause {
        cx.error(
            where_clause,
            "struct with where-clause is not supported yet",
        );
    }

    let mut fields = Vec::new();
    for field in named_fields.named {
        let ident = field.ident.unwrap();
        let mut cfg = CfgExpr::Unconditional;
        let mut doc = Doc::new();
        let mut cxx_name = None;
        let mut rust_name = None;
        let attrs = attrs::parse(
            cx,
            field.attrs,
            attrs::Parser {
                cfg: Some(&mut cfg),
                doc: Some(&mut doc),
                cxx_name: Some(&mut cxx_name),
                rust_name: Some(&mut rust_name),
                ..Default::default()
            },
        );
        let ty = match parse_type(&field.ty) {
            Ok(ty) => ty,
            Err(err) => {
                cx.push(err);
                continue;
            }
        };
        let visibility = visibility_pub(&field.vis, ident.span());
        let name = pair(Namespace::default(), &ident, cxx_name, rust_name);
        let colon_token = field.colon_token.unwrap();
        fields.push(Var {
            cfg,
            doc,
            attrs,
            visibility,
            name,
            colon_token,
            ty,
        });
    }

    let struct_token = item.struct_token;
    let visibility = visibility_pub(&item.vis, struct_token.span);
    let name = pair(namespace, &item.ident, cxx_name, rust_name);
    let generics = Lifetimes {
        lt_token: item.generics.lt_token,
        lifetimes,
        gt_token: item.generics.gt_token,
    };
    let brace_token = named_fields.brace_token;

    Ok(Api::Struct(Struct {
        cfg,
        doc,
        derives,
        attrs,
        visibility,
        struct_token,
        name,
        generics,
        brace_token,
        fields,
    }))
}

fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {
    let mut cfg = CfgExpr::Unconditional;
    let mut doc = Doc::new();
    let mut derives = Vec::new();
    let mut repr = None;
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let mut variants_from_header = None;
    let attrs = attrs::parse(
        cx,
        item.attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            derives: Some(&mut derives),
            repr: Some(&mut repr),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            variants_from_header: Some(&mut variants_from_header),
            ..Default::default()
        },
    );

    if !item.generics.params.is_empty() {
        let vis = &item.vis;
        let enum_token = item.enum_token;
        let ident = &item.ident;
        let generics = &item.generics;
        let span = quote!(#vis #enum_token #ident #generics);
        cx.error(span, "enum with generic parameters is not supported");
    } else if let Some(where_clause) = &item.generics.where_clause {
        cx.error(where_clause, "enum with where-clause is not supported");
    }

    let mut variants = Vec::new();
    let mut discriminants = DiscriminantSet::new(repr);
    for variant in item.variants {
        match parse_variant(cx, variant, &mut discriminants) {
            Ok(variant) => variants.push(variant),
            Err(err) => cx.push(err),
        }
    }

    let enum_token = item.enum_token;
    let visibility = visibility_pub(&item.vis, enum_token.span);
    let brace_token = item.brace_token;

    let explicit_repr = repr.is_some();
    let mut repr = U8;
    match discriminants.inferred_repr() {
        Ok(inferred) => repr = inferred,
        Err(err) => {
            let span = quote_spanned!(brace_token.span=> #enum_token {});
            cx.error(span, err);
            variants.clear();
        }
    }

    let name = pair(namespace, &item.ident, cxx_name, rust_name);
    let repr_ident = Ident::new(repr.as_ref(), Span::call_site());
    let repr_type = Type::Ident(NamedType::new(repr_ident));
    let repr = EnumRepr::Native {
        atom: repr,
        repr_type,
    };
    let generics = Lifetimes {
        lt_token: None,
        lifetimes: Punctuated::new(),
        gt_token: None,
    };
    let variants_from_header_attr = variants_from_header;
    let variants_from_header = variants_from_header_attr.is_some();

    Api::Enum(Enum {
        cfg,
        doc,
        derives,
        attrs,
        visibility,
        enum_token,
        name,
        generics,
        brace_token,
        variants,
        variants_from_header,
        variants_from_header_attr,
        repr,
        explicit_repr,
    })
}

fn parse_variant(
    cx: &mut Errors,
    mut variant: RustVariant,
    discriminants: &mut DiscriminantSet,
) -> Result<Variant> {
    let mut cfg = CfgExpr::Unconditional;
    let mut doc = Doc::new();
    let mut cxx_name = None;
    let mut rust_name = None;
    let attrs = attrs::parse(
        cx,
        mem::take(&mut variant.attrs),
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    );

    match variant.fields {
        Fields::Unit => {}
        _ => {
            let msg = "enums with data are not supported yet";
            return Err(Error::new_spanned(variant, msg));
        }
    }

    let expr = variant.discriminant.as_ref().map(|(_, expr)| expr);
    let try_discriminant = match &expr {
        Some(lit) => discriminants.insert(lit),
        None => discriminants.insert_next(),
    };
    let discriminant = match try_discriminant {
        Ok(discriminant) => discriminant,
        Err(err) => return Err(Error::new_spanned(variant, err)),
    };

    let name = pair(Namespace::ROOT, &variant.ident, cxx_name, rust_name);
    let expr = variant.discriminant.map(|(_, expr)| expr);

    Ok(Variant {
        cfg,
        doc,
        attrs,
        name,
        discriminant,
        expr,
    })
}

fn parse_foreign_mod(
    cx: &mut Errors,
    foreign_mod: ItemForeignMod,
    out: &mut Vec<Api>,
    trusted: bool,
    namespace: &Namespace,
) {
    let lang = match parse_lang(&foreign_mod.abi) {
        Ok(lang) => lang,
        Err(err) => return cx.push(err),
    };

    match lang {
        Lang::Rust => {
            if foreign_mod.unsafety.is_some() {
                let unsafety = foreign_mod.unsafety;
                let abi = &foreign_mod.abi;
                let span = quote!(#unsafety #abi);
                cx.error(span, "extern \"Rust\" block does not need to be unsafe");
            }
        }
        Lang::Cxx => {}
    }

    let trusted = trusted || foreign_mod.unsafety.is_some();

    let mut cfg = CfgExpr::Unconditional;
    let mut namespace = namespace.clone();
    let attrs = attrs::parse(
        cx,
        foreign_mod.attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            namespace: Some(&mut namespace),
            ..Default::default()
        },
    );

    let mut items = Vec::new();
    for foreign in foreign_mod.items {
        match foreign {
            ForeignItem::Type(foreign) => {
                let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace, &attrs);
                items.push(ety);
            }
            ForeignItem::Fn(foreign) => {
                match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace, &attrs) {
                    Ok(efn) => items.push(efn),
                    Err(err) => cx.push(err),
                }
            }
            ForeignItem::Macro(foreign) if foreign.mac.path.is_ident("include") => {
                match foreign.mac.parse_body_with(parse_include) {
                    Ok(mut include) => {
                        include.cfg = cfg.clone();
                        items.push(Api::Include(include));
                    }
                    Err(err) => cx.push(err),
                }
            }
            ForeignItem::Verbatim(tokens) => {
                match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace, &attrs) {
                    Ok(api) => items.push(api),
                    Err(err) => cx.push(err),
                }
            }
            _ => cx.error(foreign, "unsupported foreign item"),
        }
    }

    if !trusted
        && items.iter().any(|api| match api {
            Api::CxxFunction(efn) => efn.unsafety.is_none(),
            _ => false,
        })
    {
        cx.error(
            foreign_mod.abi,
            "block must be declared `unsafe extern \"C++\"` if it contains any safe-to-call C++ functions",
        );
    }

    let mut types = items.iter().filter_map(|item| match item {
        Api::CxxType(ety) | Api::RustType(ety) => Some(&ety.name),
        Api::TypeAlias(alias) => Some(&alias.name),
        _ => None,
    });
    if let (Some(single_type), None) = (types.next(), types.next()) {
        let single_type = single_type.clone();
        for item in &mut items {
            if let Api::CxxFunction(efn) | Api::RustFunction(efn) = item {
                if let Some(receiver) = &mut efn.receiver {
                    if receiver.ty.rust == "Self" {
                        receiver.ty.rust = single_type.rust.clone();
                    }
                }
            }
        }
    }

    out.extend(items);
}

fn parse_lang(abi: &Abi) -> Result<Lang> {
    let name = match &abi.name {
        Some(name) => name,
        None => {
            return Err(Error::new_spanned(
                abi,
                "ABI name is required, extern \"C++\" or extern \"Rust\"",
            ));
        }
    };

    match name.value().as_str() {
        "C++" => Ok(Lang::Cxx),
        "Rust" => Ok(Lang::Rust),
        _ => Err(Error::new_spanned(
            abi,
            "unrecognized ABI, requires either \"C++\" or \"Rust\"",
        )),
    }
}

fn parse_extern_type(
    cx: &mut Errors,
    foreign_type: ForeignItemType,
    lang: Lang,
    trusted: bool,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Api {
    let mut cfg = extern_block_cfg.clone();
    let mut doc = Doc::new();
    let mut derives = Vec::new();
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let mut attrs = attrs.clone();
    attrs.extend(attrs::parse(
        cx,
        foreign_type.attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            derives: Some(&mut derives),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    ));

    let type_token = foreign_type.type_token;
    let visibility = visibility_pub(&foreign_type.vis, type_token.span);
    let name = pair(namespace, &foreign_type.ident, cxx_name, rust_name);
    let generics = extern_type_lifetimes(cx, foreign_type.generics);
    let colon_token = None;
    let bounds = Vec::new();
    let semi_token = foreign_type.semi_token;

    (match lang {
        Lang::Cxx => Api::CxxType,
        Lang::Rust => Api::RustType,
    })(ExternType {
        cfg,
        lang,
        doc,
        derives,
        attrs,
        visibility,
        type_token,
        name,
        generics,
        colon_token,
        bounds,
        semi_token,
        trusted,
    })
}

fn parse_extern_fn(
    cx: &mut Errors,
    mut foreign_fn: ForeignItemFn,
    lang: Lang,
    trusted: bool,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Result<Api> {
    let mut cfg = extern_block_cfg.clone();
    let mut doc = Doc::new();
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let mut attrs = attrs.clone();
    attrs.extend(attrs::parse(
        cx,
        mem::take(&mut foreign_fn.attrs),
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    ));

    let generics = &foreign_fn.sig.generics;
    if generics.where_clause.is_some()
        || generics.params.iter().any(|param| match param {
            GenericParam::Lifetime(lifetime) => !lifetime.bounds.is_empty(),
            GenericParam::Type(_) | GenericParam::Const(_) => true,
        })
    {
        return Err(Error::new_spanned(
            foreign_fn,
            "extern function with generic parameters is not supported yet",
        ));
    }

    if let Some(variadic) = &foreign_fn.sig.variadic {
        return Err(Error::new_spanned(
            variadic,
            "variadic function is not supported yet",
        ));
    }

    if foreign_fn.sig.asyncness.is_some() && !cfg!(feature = "experimental-async-fn") {
        return Err(Error::new_spanned(
            foreign_fn,
            "async function is not directly supported yet, but see https://cxx.rs/async.html \
            for a working approach, and https://github.com/pcwalton/cxx-async for some helpers; \
            eventually what you wrote will work but it isn't integrated into the cxx::bridge \
            macro yet",
        ));
    }

    if foreign_fn.sig.constness.is_some() {
        return Err(Error::new_spanned(
            foreign_fn,
            "const extern function is not supported",
        ));
    }

    if let Some(abi) = &foreign_fn.sig.abi {
        return Err(Error::new_spanned(
            abi,
            "explicit ABI on extern function is not supported",
        ));
    }

    let mut receiver = None;
    let mut args = Punctuated::new();
    for arg in foreign_fn.sig.inputs.pairs() {
        let (arg, comma) = arg.into_tuple();
        match arg {
            FnArg::Receiver(arg) => {
                if let Some((ampersand, lifetime)) = &arg.reference {
                    receiver = Some(Receiver {
                        pinned: false,
                        ampersand: *ampersand,
                        lifetime: lifetime.clone(),
                        mutable: arg.mutability.is_some(),
                        var: arg.self_token,
                        colon_token: Token![:](arg.self_token.span),
                        ty: NamedType::new(Ident::new("Self", arg.self_token.span)),
                        shorthand: true,
                        pin_tokens: None,
                        mutability: arg.mutability,
                    });
                    continue;
                }
                if let Some(colon_token) = arg.colon_token {
                    let ty = parse_type(&arg.ty)?;
                    if let Type::Ref(reference) = ty {
                        if let Type::Ident(ident) = reference.inner {
                            receiver = Some(Receiver {
                                pinned: reference.pinned,
                                ampersand: reference.ampersand,
                                lifetime: reference.lifetime,
                                mutable: reference.mutable,
                                var: Token![self](ident.rust.span()),
                                colon_token,
                                ty: ident,
                                shorthand: false,
                                pin_tokens: reference.pin_tokens,
                                mutability: reference.mutability,
                            });
                            continue;
                        }
                    }
                }
                return Err(Error::new_spanned(arg, "unsupported method receiver"));
            }
            FnArg::Typed(arg) => {
                let ident = match arg.pat.as_ref() {
                    Pat::Ident(pat) => pat.ident.clone(),
                    Pat::Wild(pat) => {
                        Ident::new(&format!("arg{}", args.len()), pat.underscore_token.span)
                    }
                    _ => return Err(Error::new_spanned(arg, "unsupported signature")),
                };
                let ty = parse_type(&arg.ty)?;
                let cfg = CfgExpr::Unconditional;
                let doc = Doc::new();
                let attrs = OtherAttrs::none();
                let visibility = Token![pub](ident.span());
                let name = pair(Namespace::default(), &ident, None, None);
                let colon_token = arg.colon_token;
                args.push_value(Var {
                    cfg,
                    doc,
                    attrs,
                    visibility,
                    name,
                    colon_token,
                    ty,
                });
                if let Some(comma) = comma {
                    args.push_punct(*comma);
                }
            }
        }
    }

    let mut throws_tokens = None;
    let ret = parse_return_type(&foreign_fn.sig.output, &mut throws_tokens)?;
    let throws = throws_tokens.is_some();
    let asyncness = foreign_fn.sig.asyncness;
    let unsafety = foreign_fn.sig.unsafety;
    let fn_token = foreign_fn.sig.fn_token;
    let inherited_span = unsafety.map_or(fn_token.span, |unsafety| unsafety.span);
    let visibility = visibility_pub(&foreign_fn.vis, inherited_span);
    let name = pair(namespace, &foreign_fn.sig.ident, cxx_name, rust_name);
    let generics = generics.clone();
    let paren_token = foreign_fn.sig.paren_token;
    let semi_token = foreign_fn.semi_token;

    Ok(match lang {
        Lang::Cxx => Api::CxxFunction,
        Lang::Rust => Api::RustFunction,
    }(ExternFn {
        cfg,
        lang,
        doc,
        attrs,
        visibility,
        name,
        sig: Signature {
            asyncness,
            unsafety,
            fn_token,
            generics,
            receiver,
            args,
            ret,
            throws,
            paren_token,
            throws_tokens,
        },
        semi_token,
        trusted,
    }))
}

fn parse_extern_verbatim(
    cx: &mut Errors,
    tokens: TokenStream,
    lang: Lang,
    trusted: bool,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Result<Api> {
    |input: ParseStream| -> Result<Api> {
        let unparsed_attrs = input.call(Attribute::parse_outer)?;
        let visibility: Visibility = input.parse()?;
        if input.peek(Token![type]) {
            parse_extern_verbatim_type(
                cx,
                unparsed_attrs,
                visibility,
                input,
                lang,
                trusted,
                extern_block_cfg,
                namespace,
                attrs,
            )
        } else if input.peek(Token![fn]) {
            parse_extern_verbatim_fn(input)
        } else {
            let span = input.cursor().token_stream();
            Err(Error::new_spanned(
                span,
                "unsupported foreign item, expected `type` or `fn`",
            ))
        }
    }
    .parse2(tokens)
}

fn parse_extern_verbatim_type(
    cx: &mut Errors,
    unparsed_attrs: Vec<Attribute>,
    visibility: Visibility,
    input: ParseStream,
    lang: Lang,
    trusted: bool,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Result<Api> {
    let type_token: Token![type] = input.parse()?;
    let ident: Ident = input.parse()?;
    let generics: Generics = input.parse()?;
    let lifetimes = extern_type_lifetimes(cx, generics);
    let lookahead = input.lookahead1();
    if lookahead.peek(Token![=]) {
        // type Alias = crate::path::to::Type;
        parse_type_alias(
            cx,
            unparsed_attrs,
            visibility,
            type_token,
            ident,
            lifetimes,
            input,
            lang,
            extern_block_cfg,
            namespace,
            attrs,
        )
    } else if lookahead.peek(Token![:]) {
        // type Opaque: Bound2 + Bound2;
        parse_extern_type_bounded(
            cx,
            unparsed_attrs,
            visibility,
            type_token,
            ident,
            lifetimes,
            input,
            lang,
            trusted,
            extern_block_cfg,
            namespace,
            attrs,
        )
    } else {
        Err(lookahead.error())
    }
}

fn extern_type_lifetimes(cx: &mut Errors, generics: Generics) -> Lifetimes {
    let mut lifetimes = Punctuated::new();
    let mut has_unsupported_generic_param = false;
    for pair in generics.params.into_pairs() {
        let (param, punct) = pair.into_tuple();
        match param {
            GenericParam::Lifetime(param) => {
                if !param.bounds.is_empty() && !has_unsupported_generic_param {
                    let msg = "lifetime parameter with bounds is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
                lifetimes.push_value(param.lifetime);
                if let Some(punct) = punct {
                    lifetimes.push_punct(punct);
                }
            }
            GenericParam::Type(param) => {
                if !has_unsupported_generic_param {
                    let msg = "extern type with generic type parameter is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
            }
            GenericParam::Const(param) => {
                if !has_unsupported_generic_param {
                    let msg = "extern type with const generic parameter is not supported yet";
                    cx.error(&param, msg);
                    has_unsupported_generic_param = true;
                }
            }
        }
    }
    Lifetimes {
        lt_token: generics.lt_token,
        lifetimes,
        gt_token: generics.gt_token,
    }
}

fn parse_extern_verbatim_fn(input: ParseStream) -> Result<Api> {
    input.parse::<RustSignature>()?;
    input.parse::<Token![;]>()?;
    unreachable!()
}

fn parse_type_alias(
    cx: &mut Errors,
    unparsed_attrs: Vec<Attribute>,
    visibility: Visibility,
    type_token: Token![type],
    ident: Ident,
    generics: Lifetimes,
    input: ParseStream,
    lang: Lang,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Result<Api> {
    let eq_token: Token![=] = input.parse()?;
    let ty: RustType = input.parse()?;
    let semi_token: Token![;] = input.parse()?;

    let mut cfg = extern_block_cfg.clone();
    let mut doc = Doc::new();
    let mut derives = Vec::new();
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let mut attrs = attrs.clone();
    attrs.extend(attrs::parse(
        cx,
        unparsed_attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            derives: Some(&mut derives),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    ));

    if lang == Lang::Rust {
        let span = quote!(#type_token #semi_token);
        let msg = "type alias in extern \"Rust\" block is not supported";
        return Err(Error::new_spanned(span, msg));
    }

    let visibility = visibility_pub(&visibility, type_token.span);
    let name = pair(namespace, &ident, cxx_name, rust_name);

    Ok(Api::TypeAlias(TypeAlias {
        cfg,
        doc,
        derives,
        attrs,
        visibility,
        type_token,
        name,
        generics,
        eq_token,
        ty,
        semi_token,
    }))
}

fn parse_extern_type_bounded(
    cx: &mut Errors,
    unparsed_attrs: Vec<Attribute>,
    visibility: Visibility,
    type_token: Token![type],
    ident: Ident,
    generics: Lifetimes,
    input: ParseStream,
    lang: Lang,
    trusted: bool,
    extern_block_cfg: &CfgExpr,
    namespace: &Namespace,
    attrs: &OtherAttrs,
) -> Result<Api> {
    let mut bounds = Vec::new();
    let colon_token: Option<Token![:]> = input.parse()?;
    if colon_token.is_some() {
        loop {
            match input.parse()? {
                TypeParamBound::Trait(TraitBound {
                    paren_token: None,
                    modifier: TraitBoundModifier::None,
                    lifetimes: None,
                    path,
                }) if if let Some(derive) = path.get_ident().and_then(Derive::from) {
                    bounds.push(derive);
                    true
                } else {
                    false
                } => {}
                bound => cx.error(bound, "unsupported trait"),
            }

            let lookahead = input.lookahead1();
            if lookahead.peek(Token![+]) {
                input.parse::<Token![+]>()?;
            } else if lookahead.peek(Token![;]) {
                break;
            } else {
                return Err(lookahead.error());
            }
        }
    }
    let semi_token: Token![;] = input.parse()?;

    let mut cfg = extern_block_cfg.clone();
    let mut doc = Doc::new();
    let mut derives = Vec::new();
    let mut namespace = namespace.clone();
    let mut cxx_name = None;
    let mut rust_name = None;
    let mut attrs = attrs.clone();
    attrs.extend(attrs::parse(
        cx,
        unparsed_attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            doc: Some(&mut doc),
            derives: Some(&mut derives),
            namespace: Some(&mut namespace),
            cxx_name: Some(&mut cxx_name),
            rust_name: Some(&mut rust_name),
            ..Default::default()
        },
    ));

    let visibility = visibility_pub(&visibility, type_token.span);
    let name = pair(namespace, &ident, cxx_name, rust_name);

    Ok(match lang {
        Lang::Cxx => Api::CxxType,
        Lang::Rust => Api::RustType,
    }(ExternType {
        cfg,
        lang,
        doc,
        derives,
        attrs,
        visibility,
        type_token,
        name,
        generics,
        colon_token,
        bounds,
        semi_token,
        trusted,
    }))
}

fn parse_impl(cx: &mut Errors, imp: ItemImpl) -> Result<Api> {
    let impl_token = imp.impl_token;

    let mut cfg = CfgExpr::Unconditional;
    attrs::parse(
        cx,
        imp.attrs,
        attrs::Parser {
            cfg: Some(&mut cfg),
            ..Default::default()
        },
    );

    if !imp.items.is_empty() {
        let mut span = Group::new(Delimiter::Brace, TokenStream::new());
        span.set_span(imp.brace_token.span.join());
        return Err(Error::new_spanned(span, "expected an empty impl block"));
    }

    if let Some((bang, path, for_token)) = &imp.trait_ {
        let self_ty = &imp.self_ty;
        let span = quote!(#bang #path #for_token #self_ty);
        return Err(Error::new_spanned(
            span,
            "unexpected impl, expected something like `impl UniquePtr<T> {}`",
        ));
    }

    if let Some(where_clause) = imp.generics.where_clause {
        return Err(Error::new_spanned(
            where_clause,
            "where-clause on an impl is not supported yet",
        ));
    }
    let mut impl_generics = Lifetimes {
        lt_token: imp.generics.lt_token,
        lifetimes: Punctuated::new(),
        gt_token: imp.generics.gt_token,
    };
    for pair in imp.generics.params.into_pairs() {
        let (param, punct) = pair.into_tuple();
        match param {
            GenericParam::Lifetime(def) if def.bounds.is_empty() => {
                impl_generics.lifetimes.push_value(def.lifetime);
                if let Some(punct) = punct {
                    impl_generics.lifetimes.push_punct(punct);
                }
            }
            _ => {
                let span = quote!(#impl_token #impl_generics);
                return Err(Error::new_spanned(
                    span,
                    "generic parameter on an impl is not supported yet",
                ));
            }
        }
    }

    let mut negative_token = None;
    let mut self_ty = *imp.self_ty;
    if let RustType::Verbatim(ty) = &self_ty {
        let mut iter = ty.clone().into_iter();
        if let Some(TokenTree::Punct(punct)) = iter.next() {
            if punct.as_char() == '!' {
                let ty = iter.collect::<TokenStream>();
                if !ty.is_empty() {
                    negative_token = Some(Token![!](punct.span()));
                    self_ty = syn::parse2(ty)?;
                }
            }
        }
    }

    let ty = parse_type(&self_ty)?;
    let ty_generics = match &ty {
        Type::RustBox(ty)
        | Type::RustVec(ty)
        | Type::UniquePtr(ty)
        | Type::SharedPtr(ty)
        | Type::WeakPtr(ty)
        | Type::CxxVector(ty) => match &ty.inner {
            Type::Ident(ident) => ident.generics.clone(),
            _ => Lifetimes::default(),
        },
        Type::Ident(_)
        | Type::Ref(_)
        | Type::Ptr(_)
        | Type::Str(_)
        | Type::Fn(_)
        | Type::Void(_)
        | Type::SliceRef(_)
        | Type::Array(_) => Lifetimes::default(),
    };

    let negative = negative_token.is_some();
    let brace_token = imp.brace_token;

    Ok(Api::Impl(Impl {
        cfg,
        impl_token,
        impl_generics,
        negative,
        ty,
        ty_generics,
        brace_token,
        negative_token,
    }))
}

fn parse_include(input: ParseStream) -> Result<Include> {
    if input.peek(LitStr) {
        let lit: LitStr = input.parse()?;
        let span = lit.span();
        return Ok(Include {
            cfg: CfgExpr::Unconditional,
            path: lit.value(),
            kind: IncludeKind::Quoted,
            begin_span: span,
            end_span: span,
        });
    }

    if input.peek(Token![<]) {
        let mut path = String::new();

        let langle: Token![<] = input.parse()?;
        while !input.is_empty() && !input.peek(Token![>]) {
            let token: TokenTree = input.parse()?;
            match token {
                TokenTree::Ident(token) => path += &token.to_string(),
                TokenTree::Literal(token)
                    if token
                        .to_string()
                        .starts_with(|ch: char| ch.is_ascii_digit()) =>
                {
                    path += &token.to_string();
                }
                TokenTree::Punct(token) => path.push(token.as_char()),
                _ => return Err(Error::new(token.span(), "unexpected token in include path")),
            }
        }
        let rangle: Token![>] = input.parse()?;

        return Ok(Include {
            cfg: CfgExpr::Unconditional,
            path,
            kind: IncludeKind::Bracketed,
            begin_span: langle.span,
            end_span: rangle.span,
        });
    }

    Err(input.error("expected \"quoted/path/to\" or <bracketed/path/to>"))
}

fn parse_type(ty: &RustType) -> Result<Type> {
    match ty {
        RustType::Reference(ty) => parse_type_reference(ty),
        RustType::Ptr(ty) => parse_type_ptr(ty),
        RustType::Path(ty) => parse_type_path(ty),
        RustType::Array(ty) => parse_type_array(ty),
        RustType::BareFn(ty) => parse_type_fn(ty),
        RustType::Tuple(ty) if ty.elems.is_empty() => Ok(Type::Void(ty.paren_token.span.join())),
        _ => Err(Error::new_spanned(ty, "unsupported type")),
    }
}

fn parse_type_reference(ty: &TypeReference) -> Result<Type> {
    let ampersand = ty.and_token;
    let lifetime = ty.lifetime.clone();
    let mutable = ty.mutability.is_some();
    let mutability = ty.mutability;

    if let RustType::Slice(slice) = ty.elem.as_ref() {
        let inner = parse_type(&slice.elem)?;
        let bracket = slice.bracket_token;
        return Ok(Type::SliceRef(Box::new(SliceRef {
            ampersand,
            lifetime,
            mutable,
            bracket,
            inner,
            mutability,
        })));
    }

    let inner = parse_type(&ty.elem)?;
    let pinned = false;
    let pin_tokens = None;

    Ok(match &inner {
        Type::Ident(ident) if ident.rust == "str" => {
            if ty.mutability.is_some() {
                return Err(Error::new_spanned(ty, "unsupported type"));
            } else {
                Type::Str
            }
        }
        _ => Type::Ref,
    }(Box::new(Ref {
        pinned,
        ampersand,
        lifetime,
        mutable,
        inner,
        pin_tokens,
        mutability,
    })))
}

fn parse_type_ptr(ty: &TypePtr) -> Result<Type> {
    let star = ty.star_token;
    let mutable = ty.mutability.is_some();
    let constness = ty.const_token;
    let mutability = ty.mutability;

    let inner = parse_type(&ty.elem)?;

    Ok(Type::Ptr(Box::new(Ptr {
        star,
        mutable,
        inner,
        mutability,
        constness,
    })))
}

fn parse_type_path(ty: &TypePath) -> Result<Type> {
    let path = &ty.path;
    if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {
        let segment = &path.segments[0];
        let ident = segment.ident.clone();
        match &segment.arguments {
            PathArguments::None => return Ok(Type::Ident(NamedType::new(ident))),
            PathArguments::AngleBracketed(generic) => {
                if ident == "UniquePtr" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::UniquePtr(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "SharedPtr" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::SharedPtr(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "WeakPtr" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::WeakPtr(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "CxxVector" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::CxxVector(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "Box" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::RustBox(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "Vec" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        return Ok(Type::RustVec(Box::new(Ty1 {
                            name: ident,
                            langle: generic.lt_token,
                            inner,
                            rangle: generic.gt_token,
                        })));
                    }
                } else if ident == "Pin" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        let inner = parse_type(arg)?;
                        let pin_token = kw::Pin(ident.span());
                        if let Type::Ref(mut inner) = inner {
                            inner.pinned = true;
                            inner.pin_tokens =
                                Some((pin_token, generic.lt_token, generic.gt_token));
                            return Ok(Type::Ref(inner));
                        }
                    }
                } else {
                    let mut lifetimes = Punctuated::new();
                    let mut only_lifetimes = true;
                    for pair in generic.args.pairs() {
                        let (param, punct) = pair.into_tuple();
                        if let GenericArgument::Lifetime(param) = param {
                            lifetimes.push_value(param.clone());
                            if let Some(punct) = punct {
                                lifetimes.push_punct(*punct);
                            }
                        } else {
                            only_lifetimes = false;
                            break;
                        }
                    }
                    if only_lifetimes {
                        return Ok(Type::Ident(NamedType {
                            rust: ident,
                            generics: Lifetimes {
                                lt_token: Some(generic.lt_token),
                                lifetimes,
                                gt_token: Some(generic.gt_token),
                            },
                        }));
                    }
                }
            }
            PathArguments::Parenthesized(_) => {}
        }
    }

    Err(Error::new_spanned(ty, "unsupported type"))
}

fn parse_type_array(ty: &TypeArray) -> Result<Type> {
    let inner = parse_type(&ty.elem)?;

    let len_expr = if let Expr::Lit(lit) = &ty.len {
        lit
    } else {
        let msg = "unsupported expression, array length must be an integer literal";
        return Err(Error::new_spanned(&ty.len, msg));
    };

    let len_token = if let Lit::Int(int) = &len_expr.lit {
        int.clone()
    } else {
        let msg = "array length must be an integer literal";
        return Err(Error::new_spanned(len_expr, msg));
    };

    let len = len_token.base10_parse::<usize>()?;
    if len == 0 {
        let msg = "array with zero size is not supported";
        return Err(Error::new_spanned(ty, msg));
    }

    let bracket = ty.bracket_token;
    let semi_token = ty.semi_token;

    Ok(Type::Array(Box::new(Array {
        bracket,
        inner,
        semi_token,
        len,
        len_token,
    })))
}

fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
    if ty.lifetimes.is_some() {
        return Err(Error::new_spanned(
            ty,
            "function pointer with lifetime parameters is not supported yet",
        ));
    }

    if ty.variadic.is_some() {
        return Err(Error::new_spanned(
            ty,
            "variadic function pointer is not supported yet",
        ));
    }

    let args = ty
        .inputs
        .iter()
        .enumerate()
        .map(|(i, arg)| {
            let (ident, colon_token) = match &arg.name {
                Some((ident, colon_token)) => (ident.clone(), *colon_token),
                None => {
                    let fn_span = ty.paren_token.span.join();
                    let ident = format_ident!("arg{}", i, span = fn_span);
                    let colon_token = Token![:](fn_span);
                    (ident, colon_token)
                }
            };
            let ty = parse_type(&arg.ty)?;
            let cfg = CfgExpr::Unconditional;
            let doc = Doc::new();
            let attrs = OtherAttrs::none();
            let visibility = Token![pub](ident.span());
            let name = pair(Namespace::default(), &ident, None, None);
            Ok(Var {
                cfg,
                doc,
                attrs,
                visibility,
                name,
                colon_token,
                ty,
            })
        })
        .collect::<Result<_>>()?;

    let mut throws_tokens = None;
    let ret = parse_return_type(&ty.output, &mut throws_tokens)?;
    let throws = throws_tokens.is_some();

    let asyncness = None;
    let unsafety = ty.unsafety;
    let fn_token = ty.fn_token;
    let generics = Generics::default();
    let receiver = None;
    let paren_token = ty.paren_token;

    Ok(Type::Fn(Box::new(Signature {
        asyncness,
        unsafety,
        fn_token,
        generics,
        receiver,
        args,
        ret,
        throws,
        paren_token,
        throws_tokens,
    })))
}

fn parse_return_type(
    ty: &ReturnType,
    throws_tokens: &mut Option<(kw::Result, Token![<], Token![>])>,
) -> Result<Option<Type>> {
    let mut ret = match ty {
        ReturnType::Default => return Ok(None),
        ReturnType::Type(_, ret) => ret.as_ref(),
    };

    if let RustType::Path(ty) = ret {
        let path = &ty.path;
        if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {
            let segment = &path.segments[0];
            let ident = segment.ident.clone();
            if let PathArguments::AngleBracketed(generic) = &segment.arguments {
                if ident == "Result" && generic.args.len() == 1 {
                    if let GenericArgument::Type(arg) = &generic.args[0] {
                        ret = arg;
                        *throws_tokens =
                            Some((kw::Result(ident.span()), generic.lt_token, generic.gt_token));
                    }
                }
            }
        }
    }

    match parse_type(ret)? {
        Type::Void(_) => Ok(None),
        ty => Ok(Some(ty)),
    }
}

fn visibility_pub(vis: &Visibility, inherited: Span) -> Token![pub] {
    Token![pub](match vis {
        Visibility::Public(vis) => vis.span,
        Visibility::Restricted(vis) => vis.pub_token.span,
        Visibility::Inherited => inherited,
    })
}

fn pair(
    namespace: Namespace,
    default: &Ident,
    cxx: Option<ForeignName>,
    rust: Option<Ident>,
) -> Pair {
    Pair {
        namespace,
        cxx: cxx
            .unwrap_or_else(|| ForeignName::parse(&default.to_string(), default.span()).unwrap()),
        rust: rust.unwrap_or_else(|| default.clone()),
    }
}
