// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
// Ana Hobden (@hoverbear) <operator@hoverbear.org>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
// MIT/Apache 2.0 license.

use std::env;

use heck::{ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase};
use proc_macro2::{self, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
use syn::DeriveInput;
use syn::{self, ext::IdentExt, spanned::Spanned, Attribute, Field, Ident, LitStr, Type, Variant};

use crate::attr::*;
use crate::utils::{extract_doc_comment, format_doc_comment, inner_type, is_simple_ty, Sp, Ty};

/// Default casing style for generated arguments.
pub const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab;

/// Default casing style for environment variables
pub const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake;

#[derive(Clone)]
pub struct Item {
    name: Name,
    casing: Sp<CasingStyle>,
    env_casing: Sp<CasingStyle>,
    ty: Option<Type>,
    doc_comment: Vec<Method>,
    methods: Vec<Method>,
    deprecations: Vec<Deprecation>,
    value_parser: Option<ValueParser>,
    action: Option<Action>,
    verbatim_doc_comment: bool,
    force_long_help: bool,
    next_display_order: Option<Method>,
    next_help_heading: Option<Method>,
    is_enum: bool,
    is_positional: bool,
    skip_group: bool,
    group_id: Name,
    group_methods: Vec<Method>,
    kind: Sp<Kind>,
}

impl Item {
    pub fn from_args_struct(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
        let ident = input.ident.clone();
        let span = input.ident.span();
        let attrs = &input.attrs;
        let argument_casing = Sp::new(DEFAULT_CASING, span);
        let env_casing = Sp::new(DEFAULT_ENV_CASING, span);
        let kind = Sp::new(Kind::Command(Sp::new(Ty::Other, span)), span);

        let mut res = Self::new(name, ident, None, argument_casing, env_casing, kind);
        let parsed_attrs = ClapAttr::parse_all(attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        res.push_doc_comment(attrs, "about", Some("long_about"));

        Ok(res)
    }

    pub fn from_subcommand_enum(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
        let ident = input.ident.clone();
        let span = input.ident.span();
        let attrs = &input.attrs;
        let argument_casing = Sp::new(DEFAULT_CASING, span);
        let env_casing = Sp::new(DEFAULT_ENV_CASING, span);
        let kind = Sp::new(Kind::Command(Sp::new(Ty::Other, span)), span);

        let mut res = Self::new(name, ident, None, argument_casing, env_casing, kind);
        let parsed_attrs = ClapAttr::parse_all(attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        res.push_doc_comment(attrs, "about", Some("long_about"));

        Ok(res)
    }

    pub fn from_value_enum(input: &DeriveInput, name: Name) -> Result<Self, syn::Error> {
        let ident = input.ident.clone();
        let span = input.ident.span();
        let attrs = &input.attrs;
        let argument_casing = Sp::new(DEFAULT_CASING, span);
        let env_casing = Sp::new(DEFAULT_ENV_CASING, span);
        let kind = Sp::new(Kind::Value, span);

        let mut res = Self::new(name, ident, None, argument_casing, env_casing, kind);
        let parsed_attrs = ClapAttr::parse_all(attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        // Ignoring `push_doc_comment` as there is no top-level clap builder to add documentation
        // to

        if res.has_explicit_methods() {
            abort!(
                res.methods[0].name.span(),
                "{} doesn't exist for `ValueEnum` enums",
                res.methods[0].name
            );
        }

        Ok(res)
    }

    pub fn from_subcommand_variant(
        variant: &Variant,
        struct_casing: Sp<CasingStyle>,
        env_casing: Sp<CasingStyle>,
    ) -> Result<Self, syn::Error> {
        let name = variant.ident.clone();
        let ident = variant.ident.clone();
        let span = variant.span();
        let ty = match variant.fields {
            syn::Fields::Unnamed(syn::FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
                Ty::from_syn_ty(&unnamed[0].ty)
            }
            syn::Fields::Named(_) | syn::Fields::Unnamed(..) | syn::Fields::Unit => {
                Sp::new(Ty::Other, span)
            }
        };
        let kind = Sp::new(Kind::Command(ty), span);
        let mut res = Self::new(
            Name::Derived(name),
            ident,
            None,
            struct_casing,
            env_casing,
            kind,
        );
        let parsed_attrs = ClapAttr::parse_all(&variant.attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        if matches!(&*res.kind, Kind::Command(_) | Kind::Subcommand(_)) {
            res.push_doc_comment(&variant.attrs, "about", Some("long_about"));
        }

        match &*res.kind {
            Kind::Flatten(_) => {
                if res.has_explicit_methods() {
                    abort!(
                        res.kind.span(),
                        "methods are not allowed for flattened entry"
                    );
                }
            }

            Kind::Subcommand(_)
            | Kind::ExternalSubcommand
            | Kind::FromGlobal(_)
            | Kind::Skip(_, _)
            | Kind::Command(_)
            | Kind::Value
            | Kind::Arg(_) => (),
        }

        Ok(res)
    }

    pub fn from_value_enum_variant(
        variant: &Variant,
        argument_casing: Sp<CasingStyle>,
        env_casing: Sp<CasingStyle>,
    ) -> Result<Self, syn::Error> {
        let ident = variant.ident.clone();
        let span = variant.span();
        let kind = Sp::new(Kind::Value, span);
        let mut res = Self::new(
            Name::Derived(variant.ident.clone()),
            ident,
            None,
            argument_casing,
            env_casing,
            kind,
        );
        let parsed_attrs = ClapAttr::parse_all(&variant.attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        if matches!(&*res.kind, Kind::Value) {
            res.push_doc_comment(&variant.attrs, "help", None);
        }

        Ok(res)
    }

    pub fn from_args_field(
        field: &Field,
        struct_casing: Sp<CasingStyle>,
        env_casing: Sp<CasingStyle>,
    ) -> Result<Self, syn::Error> {
        let name = field.ident.clone().unwrap();
        let ident = field.ident.clone().unwrap();
        let span = field.span();
        let ty = Ty::from_syn_ty(&field.ty);
        let kind = Sp::new(Kind::Arg(ty), span);
        let mut res = Self::new(
            Name::Derived(name),
            ident,
            Some(field.ty.clone()),
            struct_casing,
            env_casing,
            kind,
        );
        let parsed_attrs = ClapAttr::parse_all(&field.attrs)?;
        res.infer_kind(&parsed_attrs)?;
        res.push_attrs(&parsed_attrs)?;
        if matches!(&*res.kind, Kind::Arg(_)) {
            res.push_doc_comment(&field.attrs, "help", Some("long_help"));
        }

        match &*res.kind {
            Kind::Flatten(_) => {
                if res.has_explicit_methods() {
                    abort!(
                        res.kind.span(),
                        "methods are not allowed for flattened entry"
                    );
                }
            }

            Kind::Subcommand(_) => {
                if res.has_explicit_methods() {
                    abort!(
                        res.kind.span(),
                        "methods in attributes are not allowed for subcommand"
                    );
                }
            }
            Kind::Skip(_, _)
            | Kind::FromGlobal(_)
            | Kind::Arg(_)
            | Kind::Command(_)
            | Kind::Value
            | Kind::ExternalSubcommand => {}
        }

        Ok(res)
    }

    fn new(
        name: Name,
        ident: Ident,
        ty: Option<Type>,
        casing: Sp<CasingStyle>,
        env_casing: Sp<CasingStyle>,
        kind: Sp<Kind>,
    ) -> Self {
        let group_id = Name::Derived(ident);
        Self {
            name,
            ty,
            casing,
            env_casing,
            doc_comment: vec![],
            methods: vec![],
            deprecations: vec![],
            value_parser: None,
            action: None,
            verbatim_doc_comment: false,
            force_long_help: false,
            next_display_order: None,
            next_help_heading: None,
            is_enum: false,
            is_positional: true,
            skip_group: false,
            group_id,
            group_methods: vec![],
            kind,
        }
    }

    fn push_method(&mut self, kind: AttrKind, name: Ident, arg: impl ToTokens) {
        self.push_method_(kind, name, arg.to_token_stream());
    }

    fn push_method_(&mut self, kind: AttrKind, name: Ident, arg: TokenStream) {
        if name == "id" {
            match kind {
                AttrKind::Command | AttrKind::Value => {
                    self.deprecations.push(Deprecation {
                        span: name.span(),
                        id: "id_is_only_for_arg",
                        version: "4.0.0",
                        description: format!(
                            "`#[{}(id)] was allowed by mistake, instead use `#[{}(name)]`",
                            kind.as_str(),
                            kind.as_str()
                        ),
                    });
                    self.name = Name::Assigned(arg);
                }
                AttrKind::Group => {
                    self.group_id = Name::Assigned(arg);
                }
                AttrKind::Arg | AttrKind::Clap | AttrKind::StructOpt => {
                    self.name = Name::Assigned(arg);
                }
            }
        } else if name == "name" {
            match kind {
                AttrKind::Arg => {
                    self.deprecations.push(Deprecation {
                        span: name.span(),
                        id: "id_is_only_for_arg",
                        version: "4.0.0",
                        description: format!(
                            "`#[{}(name)] was allowed by mistake, instead use `#[{}(id)]` or `#[{}(value_name)]`",
                            kind.as_str(),
                            kind.as_str(),
                            kind.as_str()
                        ),
                    });
                    self.name = Name::Assigned(arg);
                }
                AttrKind::Group => self.group_methods.push(Method::new(name, arg)),
                AttrKind::Command | AttrKind::Value | AttrKind::Clap | AttrKind::StructOpt => {
                    self.name = Name::Assigned(arg);
                }
            }
        } else if name == "value_parser" {
            self.value_parser = Some(ValueParser::Explicit(Method::new(name, arg)));
        } else if name == "action" {
            self.action = Some(Action::Explicit(Method::new(name, arg)));
        } else {
            if name == "short" || name == "long" {
                self.is_positional = false;
            }
            match kind {
                AttrKind::Group => self.group_methods.push(Method::new(name, arg)),
                _ => self.methods.push(Method::new(name, arg)),
            };
        }
    }

    fn infer_kind(&mut self, attrs: &[ClapAttr]) -> Result<(), syn::Error> {
        for attr in attrs {
            if let Some(AttrValue::Call(_)) = &attr.value {
                continue;
            }

            let actual_attr_kind = *attr.kind.get();
            let kind = match &attr.magic {
                Some(MagicAttrName::FromGlobal) => {
                    if attr.value.is_some() {
                        let expr = attr.value_or_abort()?;
                        abort!(expr, "attribute `{}` does not accept a value", attr.name);
                    }
                    let ty = self
                        .kind()
                        .ty()
                        .cloned()
                        .unwrap_or_else(|| Sp::new(Ty::Other, self.kind.span()));
                    let kind = Sp::new(Kind::FromGlobal(ty), attr.name.clone().span());
                    Some(kind)
                }
                Some(MagicAttrName::Subcommand) if attr.value.is_none() => {
                    if attr.value.is_some() {
                        let expr = attr.value_or_abort()?;
                        abort!(expr, "attribute `{}` does not accept a value", attr.name);
                    }
                    let ty = self
                        .kind()
                        .ty()
                        .cloned()
                        .unwrap_or_else(|| Sp::new(Ty::Other, self.kind.span()));
                    let kind = Sp::new(Kind::Subcommand(ty), attr.name.clone().span());
                    Some(kind)
                }
                Some(MagicAttrName::ExternalSubcommand) if attr.value.is_none() => {
                    if attr.value.is_some() {
                        let expr = attr.value_or_abort()?;
                        abort!(expr, "attribute `{}` does not accept a value", attr.name);
                    }
                    let kind = Sp::new(Kind::ExternalSubcommand, attr.name.clone().span());
                    Some(kind)
                }
                Some(MagicAttrName::Flatten) if attr.value.is_none() => {
                    if attr.value.is_some() {
                        let expr = attr.value_or_abort()?;
                        abort!(expr, "attribute `{}` does not accept a value", attr.name);
                    }
                    let ty = self
                        .kind()
                        .ty()
                        .cloned()
                        .unwrap_or_else(|| Sp::new(Ty::Other, self.kind.span()));
                    let kind = Sp::new(Kind::Flatten(ty), attr.name.clone().span());
                    Some(kind)
                }
                Some(MagicAttrName::Skip) if actual_attr_kind != AttrKind::Group => {
                    let expr = attr.value.clone();
                    let kind = Sp::new(
                        Kind::Skip(expr, self.kind.attr_kind()),
                        attr.name.clone().span(),
                    );
                    Some(kind)
                }
                _ => None,
            };

            if let Some(kind) = kind {
                self.set_kind(kind)?;
            }
        }

        Ok(())
    }

    fn push_attrs(&mut self, attrs: &[ClapAttr]) -> Result<(), syn::Error> {
        for attr in attrs {
            let actual_attr_kind = *attr.kind.get();
            let expected_attr_kind = self.kind.attr_kind();
            match (actual_attr_kind, expected_attr_kind) {
                (AttrKind::Clap, _) | (AttrKind::StructOpt, _) => {
                    self.deprecations.push(Deprecation::attribute(
                        "4.0.0",
                        actual_attr_kind,
                        expected_attr_kind,
                        attr.kind.span(),
                    ));
                }

                (AttrKind::Group, AttrKind::Command) => {}

                _ if attr.kind != expected_attr_kind => {
                    abort!(
                        attr.kind.span(),
                        "Expected `{}` attribute instead of `{}`",
                        expected_attr_kind.as_str(),
                        actual_attr_kind.as_str()
                    );
                }

                _ => {}
            }

            if let Some(AttrValue::Call(tokens)) = &attr.value {
                // Force raw mode with method call syntax
                self.push_method(*attr.kind.get(), attr.name.clone(), quote!(#(#tokens),*));
                continue;
            }

            match &attr.magic {
                Some(MagicAttrName::Short) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.push_method(
                        *attr.kind.get(),
                        attr.name.clone(),
                        self.name.clone().translate_char(*self.casing),
                    );
                }

                Some(MagicAttrName::Long) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.push_method(*attr.kind.get(), attr.name.clone(), self.name.clone().translate(*self.casing));
                }

                Some(MagicAttrName::ValueParser) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.deprecations.push(Deprecation {
                        span: attr.name.span(),
                        id: "bare_value_parser",
                        version: "4.0.0",
                        description: "`#[arg(value_parser)]` is now the default and is no longer needed`".to_owned(),
                    });
                    self.value_parser = Some(ValueParser::Implicit(attr.name.clone()));
                }

                Some(MagicAttrName::Action) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.deprecations.push(Deprecation {
                        span: attr.name.span(),
                        id: "bare_action",
                        version: "4.0.0",
                        description: "`#[arg(action)]` is now the default and is no longer needed`".to_owned(),
                    });
                    self.action = Some(Action::Implicit(attr.name.clone()));
                }

                Some(MagicAttrName::Env) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.push_method(
                        *attr.kind.get(),
                        attr.name.clone(),
                        self.name.clone().translate(*self.env_casing),
                    );
                }

                Some(MagicAttrName::ValueEnum) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.is_enum = true
                }

                Some(MagicAttrName::VerbatimDocComment) if attr.value.is_none() => {
                    self.verbatim_doc_comment = true
                }

                Some(MagicAttrName::About) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    if let Some(method) =
                        Method::from_env(attr.name.clone(), "CARGO_PKG_DESCRIPTION")?
                    {
                        self.methods.push(method);
                    }
                }

                Some(MagicAttrName::LongAbout) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    self.force_long_help = true;
                }

                Some(MagicAttrName::LongHelp) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    self.force_long_help = true;
                }

                Some(MagicAttrName::Author) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    if let Some(method) = Method::from_env(attr.name.clone(), "CARGO_PKG_AUTHORS")? {
                        self.methods.push(method);
                    }
                }

                Some(MagicAttrName::Version) if attr.value.is_none() => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    if let Some(method) = Method::from_env(attr.name.clone(), "CARGO_PKG_VERSION")? {
                        self.methods.push(method);
                    }
                }

                Some(MagicAttrName::DefaultValueT) => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    let ty = if let Some(ty) = self.ty.as_ref() {
                        ty
                    } else {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_value_t)] (without an argument) can be used \
                            only on field level\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    };

                    let val = if let Some(expr) = &attr.value {
                        quote!(#expr)
                    } else {
                        quote!(<#ty as ::std::default::Default>::default())
                    };

                    let val = if attrs
                        .iter()
                        .any(|a| a.magic == Some(MagicAttrName::ValueEnum))
                    {
                        quote_spanned!(attr.name.clone().span()=> {
                            static DEFAULT_VALUE: ::std::sync::OnceLock<String> = ::std::sync::OnceLock::new();
                            let s = DEFAULT_VALUE.get_or_init(|| {
                                let val: #ty = #val;
                                clap::ValueEnum::to_possible_value(&val).unwrap().get_name().to_owned()
                            });
                            let s: &'static str = &*s;
                            s
                        })
                    } else {
                        quote_spanned!(attr.name.clone().span()=> {
                            static DEFAULT_VALUE: ::std::sync::OnceLock<String> = ::std::sync::OnceLock::new();
                            let s = DEFAULT_VALUE.get_or_init(|| {
                                let val: #ty = #val;
                                ::std::string::ToString::to_string(&val)
                            });
                            let s: &'static str = &*s;
                            s
                        })
                    };

                    let raw_ident = Ident::new("default_value", attr.name.clone().span());
                    self.methods.push(Method::new(raw_ident, val));
                }

                Some(MagicAttrName::DefaultValuesT) => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    let ty = if let Some(ty) = self.ty.as_ref() {
                        ty
                    } else {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_values_t)] (without an argument) can be used \
                            only on field level\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    };
                    let expr = attr.value_or_abort()?;

                    let container_type = Ty::from_syn_ty(ty);
                    if *container_type != Ty::Vec {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_values_t)] can be used only on Vec types\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    }
                    let inner_type = inner_type(ty);

                    // Use `Borrow<#inner_type>` so we accept `&Vec<#inner_type>` and
                    // `Vec<#inner_type>`.
                    let val = if attrs
                        .iter()
                        .any(|a| a.magic == Some(MagicAttrName::ValueEnum))
                    {
                        quote_spanned!(attr.name.clone().span()=> {
                            {
                                fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> impl Iterator<Item=String>
                                where
                                    T: ::std::borrow::Borrow<#inner_type>
                                {
                                    iterable
                                        .into_iter()
                                        .map(|val| {
                                            clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name().to_owned()
                                        })
                                }

                                static DEFAULT_STRINGS: ::std::sync::OnceLock<Vec<String>> = ::std::sync::OnceLock::new();
                                static DEFAULT_VALUES: ::std::sync::OnceLock<Vec<&str>> = ::std::sync::OnceLock::new();
                                DEFAULT_VALUES.get_or_init(|| {
                                    DEFAULT_STRINGS.get_or_init(|| iter_to_vals(#expr).collect()).iter().map(::std::string::String::as_str).collect()
                                }).iter().copied()
                            }
                        })
                    } else {
                        quote_spanned!(attr.name.clone().span()=> {
                            {
                                fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> impl Iterator<Item=String>
                                where
                                    T: ::std::borrow::Borrow<#inner_type>
                                {
                                    iterable.into_iter().map(|val| val.borrow().to_string())
                                }

                                static DEFAULT_STRINGS: ::std::sync::OnceLock<Vec<String>> = ::std::sync::OnceLock::new();
                                static DEFAULT_VALUES: ::std::sync::OnceLock<Vec<&str>> = ::std::sync::OnceLock::new();
                                DEFAULT_VALUES.get_or_init(|| {
                                    DEFAULT_STRINGS.get_or_init(|| iter_to_vals(#expr).collect()).iter().map(::std::string::String::as_str).collect()
                                }).iter().copied()
                            }
                        })
                    };

                    self.methods.push(Method::new(
                        Ident::new("default_values", attr.name.clone().span()),
                        val,
                    ));
                }

                Some(MagicAttrName::DefaultValueOsT) => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    let ty = if let Some(ty) = self.ty.as_ref() {
                        ty
                    } else {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_value_os_t)] (without an argument) can be used \
                            only on field level\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    };

                    let val = if let Some(expr) = &attr.value {
                        quote!(#expr)
                    } else {
                        quote!(<#ty as ::std::default::Default>::default())
                    };

                    let val = if attrs
                        .iter()
                        .any(|a| a.magic == Some(MagicAttrName::ValueEnum))
                    {
                        quote_spanned!(attr.name.clone().span()=> {
                            static DEFAULT_VALUE: ::std::sync::OnceLock<String> = ::std::sync::OnceLock::new();
                            let s = DEFAULT_VALUE.get_or_init(|| {
                                let val: #ty = #val;
                                clap::ValueEnum::to_possible_value(&val).unwrap().get_name().to_owned()
                            });
                            let s: &'static str = &*s;
                            s
                        })
                    } else {
                        quote_spanned!(attr.name.clone().span()=> {
                            static DEFAULT_VALUE: ::std::sync::OnceLock<::std::ffi::OsString> = ::std::sync::OnceLock::new();
                            let s = DEFAULT_VALUE.get_or_init(|| {
                                let val: #ty = #val;
                                ::std::ffi::OsString::from(val)
                            });
                            let s: &'static ::std::ffi::OsStr = &*s;
                            s
                        })
                    };

                    let raw_ident = Ident::new("default_value", attr.name.clone().span());
                    self.methods.push(Method::new(raw_ident, val));
                }

                Some(MagicAttrName::DefaultValuesOsT) => {
                    assert_attr_kind(attr, &[AttrKind::Arg])?;

                    let ty = if let Some(ty) = self.ty.as_ref() {
                        ty
                    } else {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_values_os_t)] (without an argument) can be used \
                            only on field level\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    };
                    let expr = attr.value_or_abort()?;

                    let container_type = Ty::from_syn_ty(ty);
                    if *container_type != Ty::Vec {
                        abort!(
                            attr.name.clone(),
                            "#[arg(default_values_os_t)] can be used only on Vec types\n\n= note: {note}\n\n",

                            note = "see \
                                https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
                    }
                    let inner_type = inner_type(ty);

                    // Use `Borrow<#inner_type>` so we accept `&Vec<#inner_type>` and
                    // `Vec<#inner_type>`.
                    let val = if attrs
                        .iter()
                        .any(|a| a.magic == Some(MagicAttrName::ValueEnum))
                    {
                        quote_spanned!(attr.name.clone().span()=> {
                            {
                                fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> impl Iterator<Item=::std::ffi::OsString>
                                where
                                    T: ::std::borrow::Borrow<#inner_type>
                                {
                                    iterable
                                        .into_iter()
                                        .map(|val| {
                                            clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name().to_owned().into()
                                        })
                                }

                                static DEFAULT_STRINGS: ::std::sync::OnceLock<Vec<::std::ffi::OsString>> = ::std::sync::OnceLock::new();
                                static DEFAULT_VALUES: ::std::sync::OnceLock<Vec<&::std::ffi::OsStr>> = ::std::sync::OnceLock::new();
                                DEFAULT_VALUES.get_or_init(|| {
                                    DEFAULT_STRINGS.get_or_init(|| iter_to_vals(#expr).collect()).iter().map(::std::ffi::OsString::as_os_str).collect()
                                }).iter().copied()
                            }
                        })
                    } else {
                        quote_spanned!(attr.name.clone().span()=> {
                            {
                                fn iter_to_vals<T>(iterable: impl IntoIterator<Item = T>) -> impl Iterator<Item=::std::ffi::OsString>
                                where
                                    T: ::std::borrow::Borrow<#inner_type>
                                {
                                    iterable.into_iter().map(|val| val.borrow().into())
                                }

                                static DEFAULT_STRINGS: ::std::sync::OnceLock<Vec<::std::ffi::OsString>> = ::std::sync::OnceLock::new();
                                static DEFAULT_VALUES: ::std::sync::OnceLock<Vec<&::std::ffi::OsStr>> = ::std::sync::OnceLock::new();
                                DEFAULT_VALUES.get_or_init(|| {
                                    DEFAULT_STRINGS.get_or_init(|| iter_to_vals(#expr).collect()).iter().map(::std::ffi::OsString::as_os_str).collect()
                                }).iter().copied()
                            }
                        })
                    };

                    self.methods.push(Method::new(
                        Ident::new("default_values", attr.name.clone().span()),
                        val,
                    ));
                }

                Some(MagicAttrName::NextDisplayOrder) => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    let expr = attr.value_or_abort()?;
                    self.next_display_order = Some(Method::new(attr.name.clone(), quote!(#expr)));
                }

                Some(MagicAttrName::NextHelpHeading) => {
                    assert_attr_kind(attr, &[AttrKind::Command])?;

                    let expr = attr.value_or_abort()?;
                    self.next_help_heading = Some(Method::new(attr.name.clone(), quote!(#expr)));
                }

                Some(MagicAttrName::RenameAll) => {
                    let lit = attr.lit_str_or_abort()?;
                    self.casing = CasingStyle::from_lit(lit)?;
                }

                Some(MagicAttrName::RenameAllEnv) => {
                    assert_attr_kind(attr, &[AttrKind::Command, AttrKind::Arg])?;

                    let lit = attr.lit_str_or_abort()?;
                    self.env_casing = CasingStyle::from_lit(lit)?;
                }

                Some(MagicAttrName::Skip) if actual_attr_kind == AttrKind::Group => {
                    self.skip_group = true;
                }

                None
                // Magic only for the default, otherwise just forward to the builder
                | Some(MagicAttrName::Short)
                | Some(MagicAttrName::Long)
                | Some(MagicAttrName::Env)
                | Some(MagicAttrName::About)
                | Some(MagicAttrName::LongAbout)
                | Some(MagicAttrName::LongHelp)
                | Some(MagicAttrName::Author)
                | Some(MagicAttrName::Version)
                 => {
                    let expr = attr.value_or_abort()?;
                    self.push_method(*attr.kind.get(), attr.name.clone(), expr);
                }

                // Magic only for the default, otherwise just forward to the builder
                Some(MagicAttrName::ValueParser) | Some(MagicAttrName::Action) => {
                    let expr = attr.value_or_abort()?;
                    self.push_method(*attr.kind.get(), attr.name.clone(), expr);
                }

                // Directives that never receive a value
                Some(MagicAttrName::ValueEnum)
                | Some(MagicAttrName::VerbatimDocComment) => {
                    let expr = attr.value_or_abort()?;
                    abort!(expr, "attribute `{}` does not accept a value", attr.name);
                }

                // Kinds
                Some(MagicAttrName::FromGlobal)
                | Some(MagicAttrName::Subcommand)
                | Some(MagicAttrName::ExternalSubcommand)
                | Some(MagicAttrName::Flatten)
                | Some(MagicAttrName::Skip) => {
                }
            }
        }

        if self.has_explicit_methods() {
            if let Kind::Skip(_, attr) = &*self.kind {
                abort!(
                    self.methods[0].name.span(),
                    "`{}` cannot be used with `#[{}(skip)]",
                    self.methods[0].name,
                    attr.as_str(),
                );
            }
            if let Kind::FromGlobal(_) = &*self.kind {
                abort!(
                    self.methods[0].name.span(),
                    "`{}` cannot be used with `#[arg(from_global)]",
                    self.methods[0].name,
                );
            }
        }

        Ok(())
    }

    fn push_doc_comment(&mut self, attrs: &[Attribute], short_name: &str, long_name: Option<&str>) {
        let lines = extract_doc_comment(attrs);

        if !lines.is_empty() {
            let (short_help, long_help) =
                format_doc_comment(&lines, !self.verbatim_doc_comment, self.force_long_help);
            let short_name = format_ident!("{short_name}");
            let short = Method::new(
                short_name,
                short_help
                    .map(|h| quote!(#h))
                    .unwrap_or_else(|| quote!(None)),
            );
            self.doc_comment.push(short);
            if let Some(long_name) = long_name {
                let long_name = format_ident!("{long_name}");
                let long = Method::new(
                    long_name,
                    long_help
                        .map(|h| quote!(#h))
                        .unwrap_or_else(|| quote!(None)),
                );
                self.doc_comment.push(long);
            }
        }
    }

    fn set_kind(&mut self, kind: Sp<Kind>) -> Result<(), syn::Error> {
        match (self.kind.get(), kind.get()) {
            (Kind::Arg(_), Kind::FromGlobal(_))
            | (Kind::Arg(_), Kind::Subcommand(_))
            | (Kind::Arg(_), Kind::Flatten(_))
            | (Kind::Arg(_), Kind::Skip(_, _))
            | (Kind::Command(_), Kind::Subcommand(_))
            | (Kind::Command(_), Kind::Flatten(_))
            | (Kind::Command(_), Kind::Skip(_, _))
            | (Kind::Command(_), Kind::ExternalSubcommand)
            | (Kind::Value, Kind::Skip(_, _)) => {
                self.kind = kind;
            }

            (_, _) => {
                let old = self.kind.name();
                let new = kind.name();
                abort!(kind.span(), "`{new}` cannot be used with `{old}`");
            }
        }
        Ok(())
    }

    pub fn find_default_method(&self) -> Option<&Method> {
        self.methods
            .iter()
            .find(|m| m.name == "default_value" || m.name == "default_value_os")
    }

    /// generate methods from attributes on top of struct or enum
    pub fn initial_top_level_methods(&self) -> TokenStream {
        let next_display_order = self.next_display_order.as_ref().into_iter();
        let next_help_heading = self.next_help_heading.as_ref().into_iter();
        quote!(
            #(#next_display_order)*
            #(#next_help_heading)*
        )
    }

    pub fn final_top_level_methods(&self) -> TokenStream {
        let methods = &self.methods;
        let doc_comment = &self.doc_comment;

        quote!( #(#doc_comment)* #(#methods)*)
    }

    /// generate methods on top of a field
    pub fn field_methods(&self) -> proc_macro2::TokenStream {
        let methods = &self.methods;
        let doc_comment = &self.doc_comment;
        quote!( #(#doc_comment)* #(#methods)* )
    }

    pub fn group_id(&self) -> TokenStream {
        self.group_id.clone().raw()
    }

    pub fn group_methods(&self) -> TokenStream {
        let group_methods = &self.group_methods;
        quote!( #(#group_methods)* )
    }

    pub fn deprecations(&self) -> proc_macro2::TokenStream {
        let deprecations = &self.deprecations;
        quote!( #(#deprecations)* )
    }

    pub fn next_display_order(&self) -> TokenStream {
        let next_display_order = self.next_display_order.as_ref().into_iter();
        quote!( #(#next_display_order)* )
    }

    pub fn next_help_heading(&self) -> TokenStream {
        let next_help_heading = self.next_help_heading.as_ref().into_iter();
        quote!( #(#next_help_heading)* )
    }

    pub fn id(&self) -> TokenStream {
        self.name.clone().raw()
    }

    pub fn cased_name(&self) -> TokenStream {
        self.name.clone().translate(*self.casing)
    }

    pub fn value_name(&self) -> TokenStream {
        self.name.clone().translate(CasingStyle::ScreamingSnake)
    }

    pub fn value_parser(&self, field_type: &Type) -> Method {
        self.value_parser
            .clone()
            .map(|p| {
                let inner_type = inner_type(field_type);
                p.resolve(inner_type)
            })
            .unwrap_or_else(|| {
                let inner_type = inner_type(field_type);
                if let Some(action) = self.action.as_ref() {
                    let span = action.span();
                    default_value_parser(inner_type, span)
                } else {
                    let span = self
                        .action
                        .as_ref()
                        .map(|a| a.span())
                        .unwrap_or_else(|| self.kind.span());
                    default_value_parser(inner_type, span)
                }
            })
    }

    pub fn action(&self, field_type: &Type) -> Method {
        self.action
            .clone()
            .map(|p| p.resolve(field_type))
            .unwrap_or_else(|| {
                if let Some(value_parser) = self.value_parser.as_ref() {
                    let span = value_parser.span();
                    default_action(field_type, span)
                } else {
                    let span = self
                        .value_parser
                        .as_ref()
                        .map(|a| a.span())
                        .unwrap_or_else(|| self.kind.span());
                    default_action(field_type, span)
                }
            })
    }

    pub fn kind(&self) -> Sp<Kind> {
        self.kind.clone()
    }

    pub fn is_positional(&self) -> bool {
        self.is_positional
    }

    pub fn casing(&self) -> Sp<CasingStyle> {
        self.casing
    }

    pub fn env_casing(&self) -> Sp<CasingStyle> {
        self.env_casing
    }

    pub fn has_explicit_methods(&self) -> bool {
        self.methods
            .iter()
            .any(|m| m.name != "help" && m.name != "long_help")
    }

    pub fn skip_group(&self) -> bool {
        self.skip_group
    }
}

#[derive(Clone)]
enum ValueParser {
    Explicit(Method),
    Implicit(Ident),
}

impl ValueParser {
    fn resolve(self, _inner_type: &Type) -> Method {
        match self {
            Self::Explicit(method) => method,
            Self::Implicit(ident) => default_value_parser(_inner_type, ident.span()),
        }
    }

    fn span(&self) -> Span {
        match self {
            Self::Explicit(method) => method.name.span(),
            Self::Implicit(ident) => ident.span(),
        }
    }
}

fn default_value_parser(inner_type: &Type, span: Span) -> Method {
    let func = Ident::new("value_parser", span);
    Method::new(
        func,
        quote_spanned! { span=>
            clap::value_parser!(#inner_type)
        },
    )
}

#[derive(Clone)]
pub enum Action {
    Explicit(Method),
    Implicit(Ident),
}

impl Action {
    pub fn resolve(self, _field_type: &Type) -> Method {
        match self {
            Self::Explicit(method) => method,
            Self::Implicit(ident) => default_action(_field_type, ident.span()),
        }
    }

    pub fn span(&self) -> Span {
        match self {
            Self::Explicit(method) => method.name.span(),
            Self::Implicit(ident) => ident.span(),
        }
    }
}

fn default_action(field_type: &Type, span: Span) -> Method {
    let ty = Ty::from_syn_ty(field_type);
    let args = match *ty {
        Ty::Vec | Ty::OptionVec | Ty::VecVec | Ty::OptionVecVec => {
            quote_spanned! { span=>
                clap::ArgAction::Append
            }
        }
        Ty::Option | Ty::OptionOption => {
            quote_spanned! { span=>
                clap::ArgAction::Set
            }
        }
        _ => {
            if is_simple_ty(field_type, "bool") {
                quote_spanned! { span=>
                    clap::ArgAction::SetTrue
                }
            } else {
                quote_spanned! { span=>
                    clap::ArgAction::Set
                }
            }
        }
    };

    let func = Ident::new("action", span);
    Method::new(func, args)
}

#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
pub enum Kind {
    Arg(Sp<Ty>),
    Command(Sp<Ty>),
    Value,
    FromGlobal(Sp<Ty>),
    Subcommand(Sp<Ty>),
    Flatten(Sp<Ty>),
    Skip(Option<AttrValue>, AttrKind),
    ExternalSubcommand,
}

impl Kind {
    pub fn name(&self) -> &'static str {
        match self {
            Self::Arg(_) => "arg",
            Self::Command(_) => "command",
            Self::Value => "value",
            Self::FromGlobal(_) => "from_global",
            Self::Subcommand(_) => "subcommand",
            Self::Flatten(_) => "flatten",
            Self::Skip(_, _) => "skip",
            Self::ExternalSubcommand => "external_subcommand",
        }
    }

    pub fn attr_kind(&self) -> AttrKind {
        match self {
            Self::Arg(_) => AttrKind::Arg,
            Self::Command(_) => AttrKind::Command,
            Self::Value => AttrKind::Value,
            Self::FromGlobal(_) => AttrKind::Arg,
            Self::Subcommand(_) => AttrKind::Command,
            Self::Flatten(_) => AttrKind::Command,
            Self::Skip(_, kind) => *kind,
            Self::ExternalSubcommand => AttrKind::Command,
        }
    }

    pub fn ty(&self) -> Option<&Sp<Ty>> {
        match self {
            Self::Arg(ty)
            | Self::Command(ty)
            | Self::Flatten(ty)
            | Self::FromGlobal(ty)
            | Self::Subcommand(ty) => Some(ty),
            Self::Value | Self::Skip(_, _) | Self::ExternalSubcommand => None,
        }
    }
}

#[derive(Clone)]
pub struct Method {
    name: Ident,
    args: TokenStream,
}

impl Method {
    pub fn new(name: Ident, args: TokenStream) -> Self {
        Method { name, args }
    }

    fn from_env(ident: Ident, env_var: &str) -> Result<Option<Self>, syn::Error> {
        let mut lit = match env::var(env_var) {
            Ok(val) => {
                if val.is_empty() {
                    return Ok(None);
                }
                LitStr::new(&val, ident.span())
            }
            Err(_) => {
                abort!(
                    ident,
                    "cannot derive `{}` from Cargo.toml\n\n= note: {note}\n\n= help: {help}\n\n",
                    ident,
                    note = format_args!("`{env_var}` environment variable is not set"),
                    help = format_args!("use `{ident} = \"...\"` to set {ident} manually")
                );
            }
        };

        if ident == "author" {
            let edited = process_author_str(&lit.value());
            lit = LitStr::new(&edited, lit.span());
        }

        Ok(Some(Method::new(ident, quote!(#lit))))
    }

    pub(crate) fn args(&self) -> &TokenStream {
        &self.args
    }
}

impl ToTokens for Method {
    fn to_tokens(&self, ts: &mut proc_macro2::TokenStream) {
        let Method { ref name, ref args } = self;

        let tokens = quote!( .#name(#args) );

        tokens.to_tokens(ts);
    }
}

#[derive(Clone)]
pub struct Deprecation {
    pub span: Span,
    pub id: &'static str,
    pub version: &'static str,
    pub description: String,
}

impl Deprecation {
    fn attribute(version: &'static str, old: AttrKind, new: AttrKind, span: Span) -> Self {
        Self {
            span,
            id: "old_attribute",
            version,
            description: format!(
                "Attribute `#[{}(...)]` has been deprecated in favor of `#[{}(...)]`",
                old.as_str(),
                new.as_str()
            ),
        }
    }
}

impl ToTokens for Deprecation {
    fn to_tokens(&self, ts: &mut proc_macro2::TokenStream) {
        let tokens = if cfg!(feature = "deprecated") {
            let Deprecation {
                span,
                id,
                version,
                description,
            } = self;
            let span = *span;
            let id = Ident::new(id, span);

            quote_spanned!(span=> {
                #[deprecated(since = #version, note = #description)]
                fn #id() {}
                #id();
            })
        } else {
            quote!()
        };

        tokens.to_tokens(ts);
    }
}

fn assert_attr_kind(attr: &ClapAttr, possible_kind: &[AttrKind]) -> Result<(), syn::Error> {
    if *attr.kind.get() == AttrKind::Clap || *attr.kind.get() == AttrKind::StructOpt {
        // deprecated
    } else if !possible_kind.contains(attr.kind.get()) {
        let options = possible_kind
            .iter()
            .map(|k| format!("`#[{}({})]`", k.as_str(), attr.name))
            .collect::<Vec<_>>();
        abort!(
            attr.name,
            "Unknown `#[{}({})]` attribute ({} exists)",
            attr.kind.as_str(),
            attr.name,
            options.join(", ")
        );
    }
    Ok(())
}

/// replace all `:` with `, ` when not inside the `<>`
///
/// `"author1:author2:author3" => "author1, author2, author3"`
/// `"author1 <http://website1.com>:author2" => "author1 <http://website1.com>, author2"
fn process_author_str(author: &str) -> String {
    let mut res = String::with_capacity(author.len());
    let mut inside_angle_braces = 0usize;

    for ch in author.chars() {
        if inside_angle_braces > 0 && ch == '>' {
            inside_angle_braces -= 1;
            res.push(ch);
        } else if ch == '<' {
            inside_angle_braces += 1;
            res.push(ch);
        } else if inside_angle_braces == 0 && ch == ':' {
            res.push_str(", ");
        } else {
            res.push(ch);
        }
    }

    res
}

/// Defines the casing for the attributes long representation.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CasingStyle {
    /// Indicate word boundaries with uppercase letter, excluding the first word.
    Camel,
    /// Keep all letters lowercase and indicate word boundaries with hyphens.
    Kebab,
    /// Indicate word boundaries with uppercase letter, including the first word.
    Pascal,
    /// Keep all letters uppercase and indicate word boundaries with underscores.
    ScreamingSnake,
    /// Keep all letters lowercase and indicate word boundaries with underscores.
    Snake,
    /// Keep all letters lowercase and remove word boundaries.
    Lower,
    /// Keep all letters uppercase and remove word boundaries.
    Upper,
    /// Use the original attribute name defined in the code.
    Verbatim,
}

impl CasingStyle {
    fn from_lit(name: &LitStr) -> Result<Sp<Self>, syn::Error> {
        use self::CasingStyle::*;

        let normalized = name.value().to_upper_camel_case().to_lowercase();
        let cs = |kind| Sp::new(kind, name.span());

        let s = match normalized.as_ref() {
            "camel" | "camelcase" => cs(Camel),
            "kebab" | "kebabcase" => cs(Kebab),
            "pascal" | "pascalcase" => cs(Pascal),
            "screamingsnake" | "screamingsnakecase" => cs(ScreamingSnake),
            "snake" | "snakecase" => cs(Snake),
            "lower" | "lowercase" => cs(Lower),
            "upper" | "uppercase" => cs(Upper),
            "verbatim" | "verbatimcase" => cs(Verbatim),
            s => abort!(name, "unsupported casing: `{s}`"),
        };
        Ok(s)
    }
}

#[derive(Clone)]
pub enum Name {
    Derived(Ident),
    Assigned(TokenStream),
}

impl Name {
    pub fn raw(self) -> TokenStream {
        match self {
            Name::Assigned(tokens) => tokens,
            Name::Derived(ident) => {
                let s = ident.unraw().to_string();
                quote_spanned!(ident.span()=> #s)
            }
        }
    }

    pub fn translate(self, style: CasingStyle) -> TokenStream {
        use CasingStyle::*;

        match self {
            Name::Assigned(tokens) => tokens,
            Name::Derived(ident) => {
                let s = ident.unraw().to_string();
                let s = match style {
                    Pascal => s.to_upper_camel_case(),
                    Kebab => s.to_kebab_case(),
                    Camel => s.to_lower_camel_case(),
                    ScreamingSnake => s.to_shouty_snake_case(),
                    Snake => s.to_snake_case(),
                    Lower => s.to_snake_case().replace('_', ""),
                    Upper => s.to_shouty_snake_case().replace('_', ""),
                    Verbatim => s,
                };
                quote_spanned!(ident.span()=> #s)
            }
        }
    }

    pub fn translate_char(self, style: CasingStyle) -> TokenStream {
        use CasingStyle::*;

        match self {
            Name::Assigned(tokens) => quote!( (#tokens).chars().next().unwrap() ),
            Name::Derived(ident) => {
                let s = ident.unraw().to_string();
                let s = match style {
                    Pascal => s.to_upper_camel_case(),
                    Kebab => s.to_kebab_case(),
                    Camel => s.to_lower_camel_case(),
                    ScreamingSnake => s.to_shouty_snake_case(),
                    Snake => s.to_snake_case(),
                    Lower => s.to_snake_case(),
                    Upper => s.to_shouty_snake_case(),
                    Verbatim => s,
                };

                let s = s.chars().next().unwrap();
                quote_spanned!(ident.span()=> #s)
            }
        }
    }
}
