use crate::structured_errors::StructuredDiag;
use rustc_errors::{codes::*, pluralize, Applicability, Diag, MultiSpan};
use rustc_hir as hir;
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
use rustc_session::Session;
use rustc_span::def_id::DefId;
use std::iter;

use GenericArgsInfo::*;

/// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
pub struct WrongNumberOfGenericArgs<'a, 'tcx> {
    pub(crate) tcx: TyCtxt<'tcx>,

    pub(crate) angle_brackets: AngleBrackets,

    pub(crate) gen_args_info: GenericArgsInfo,

    /// Offending path segment
    pub(crate) path_segment: &'a hir::PathSegment<'a>,

    /// Generic parameters as expected by type or trait
    pub(crate) gen_params: &'a ty::Generics,

    /// Index offset into parameters. Depends on whether `Self` is included and on
    /// number of lifetime parameters in case we're processing missing or redundant
    /// type or constant arguments.
    pub(crate) params_offset: usize,

    /// Generic arguments as provided by user
    pub(crate) gen_args: &'a hir::GenericArgs<'a>,

    /// DefId of the generic type
    pub(crate) def_id: DefId,
}

// Provides information about the kind of arguments that were provided for
// the PathSegment, for which missing generic arguments were detected
#[derive(Debug)]
pub(crate) enum AngleBrackets {
    // No angle brackets were provided, but generic arguments exist in elided form
    Implied,

    // No angle brackets were provided
    Missing,

    // Angle brackets are available, but missing some generic arguments
    Available,
}

// Information about the kind of arguments that are either missing or are unexpected
#[derive(Debug)]
pub enum GenericArgsInfo {
    MissingLifetimes {
        num_missing_args: usize,
    },
    ExcessLifetimes {
        num_redundant_args: usize,
    },
    MissingTypesOrConsts {
        num_missing_args: usize,

        // type or const generic arguments can have default values
        num_default_params: usize,

        // lifetime arguments precede type and const parameters, this
        // field gives the number of generic lifetime arguments to let
        // us infer the position of type and const generic arguments
        // in the angle brackets
        args_offset: usize,
    },

    ExcessTypesOrConsts {
        num_redundant_args: usize,

        // type or const generic arguments can have default values
        num_default_params: usize,

        // lifetime arguments precede type and const parameters, this
        // field gives the number of generic lifetime arguments to let
        // us infer the position of type and const generic arguments
        // in the angle brackets
        args_offset: usize,

        // if synthetic type arguments (e.g. `impl Trait`) are specified
        synth_provided: bool,
    },
}

impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
    pub fn new(
        tcx: TyCtxt<'tcx>,
        gen_args_info: GenericArgsInfo,
        path_segment: &'a hir::PathSegment<'_>,
        gen_params: &'a ty::Generics,
        params_offset: usize,
        gen_args: &'a hir::GenericArgs<'a>,
        def_id: DefId,
    ) -> Self {
        let angle_brackets = if gen_args.span_ext().is_none() {
            if gen_args.is_empty() { AngleBrackets::Missing } else { AngleBrackets::Implied }
        } else {
            AngleBrackets::Available
        };

        Self {
            tcx,
            angle_brackets,
            gen_args_info,
            path_segment,
            gen_params,
            params_offset,
            gen_args,
            def_id,
        }
    }

    fn missing_lifetimes(&self) -> bool {
        match self.gen_args_info {
            MissingLifetimes { .. } | ExcessLifetimes { .. } => true,
            MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => false,
        }
    }

    fn kind(&self) -> &str {
        if self.missing_lifetimes() { "lifetime" } else { "generic" }
    }

    /// Returns true if the generic type is a trait
    /// and is being referred to from one of its trait impls
    fn is_in_trait_impl(&self) -> bool {
        if self.tcx.is_trait(self.def_id) {
            // Here we check if the reference to the generic type
            // is from the 'of_trait' field of the enclosing impl

            let parent = self.tcx.parent_hir_node(self.path_segment.hir_id);
            let parent_item = self.tcx.hir_node_by_def_id(
                self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id,
            );

            // Get the HIR id of the trait ref
            let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else {
                return false;
            };

            // Get the HIR id of the 'of_trait' field of the impl
            let hir::Node::Item(hir::Item {
                kind:
                    hir::ItemKind::Impl(hir::Impl {
                        of_trait: Some(hir::TraitRef { hir_ref_id: id_in_of_trait, .. }),
                        ..
                    }),
                ..
            }) = parent_item
            else {
                return false;
            };

            // Check that trait is referred to from the of_trait field of impl
            trait_ref_id == id_in_of_trait
        } else {
            false
        }
    }

    fn num_provided_args(&self) -> usize {
        if self.missing_lifetimes() {
            self.num_provided_lifetime_args()
        } else {
            self.num_provided_type_or_const_args()
        }
    }

    fn num_provided_lifetime_args(&self) -> usize {
        match self.angle_brackets {
            AngleBrackets::Missing => 0,
            // Only lifetime arguments can be implied
            AngleBrackets::Implied => self.gen_args.args.len(),
            AngleBrackets::Available => self.gen_args.num_lifetime_params(),
        }
    }

    fn num_provided_type_or_const_args(&self) -> usize {
        match self.angle_brackets {
            AngleBrackets::Missing => 0,
            // Only lifetime arguments can be implied
            AngleBrackets::Implied => 0,
            AngleBrackets::Available => self.gen_args.num_generic_params(),
        }
    }

    fn num_expected_lifetime_args(&self) -> usize {
        let num_provided_args = self.num_provided_lifetime_args();
        match self.gen_args_info {
            MissingLifetimes { num_missing_args } => num_provided_args + num_missing_args,
            ExcessLifetimes { num_redundant_args } => num_provided_args - num_redundant_args,
            _ => 0,
        }
    }

    fn num_expected_type_or_const_args(&self) -> usize {
        let num_provided_args = self.num_provided_type_or_const_args();
        match self.gen_args_info {
            MissingTypesOrConsts { num_missing_args, .. } => num_provided_args + num_missing_args,
            ExcessTypesOrConsts { num_redundant_args, .. } => {
                num_provided_args - num_redundant_args
            }
            _ => 0,
        }
    }

    // Gives the number of expected arguments taking into account default arguments
    fn num_expected_type_or_const_args_including_defaults(&self) -> usize {
        let provided_args = self.num_provided_type_or_const_args();
        match self.gen_args_info {
            MissingTypesOrConsts { num_missing_args, num_default_params, .. } => {
                provided_args + num_missing_args - num_default_params
            }
            ExcessTypesOrConsts { num_redundant_args, num_default_params, .. } => {
                provided_args - num_redundant_args - num_default_params
            }
            _ => 0,
        }
    }

    fn num_missing_lifetime_args(&self) -> usize {
        let missing_args = self.num_expected_lifetime_args() - self.num_provided_lifetime_args();
        assert!(missing_args > 0);
        missing_args
    }

    fn num_missing_type_or_const_args(&self) -> usize {
        let missing_args = self.num_expected_type_or_const_args_including_defaults()
            - self.num_provided_type_or_const_args();
        assert!(missing_args > 0);
        missing_args
    }

    fn num_excess_lifetime_args(&self) -> usize {
        match self.gen_args_info {
            ExcessLifetimes { num_redundant_args } => num_redundant_args,
            _ => 0,
        }
    }

    fn num_excess_type_or_const_args(&self) -> usize {
        match self.gen_args_info {
            ExcessTypesOrConsts { num_redundant_args, .. } => num_redundant_args,
            _ => 0,
        }
    }

    fn too_many_args_provided(&self) -> bool {
        match self.gen_args_info {
            MissingLifetimes { .. } | MissingTypesOrConsts { .. } => false,
            ExcessLifetimes { num_redundant_args }
            | ExcessTypesOrConsts { num_redundant_args, .. } => {
                assert!(num_redundant_args > 0);
                true
            }
        }
    }

    fn not_enough_args_provided(&self) -> bool {
        match self.gen_args_info {
            MissingLifetimes { num_missing_args }
            | MissingTypesOrConsts { num_missing_args, .. } => {
                assert!(num_missing_args > 0);
                true
            }
            ExcessLifetimes { .. } | ExcessTypesOrConsts { .. } => false,
        }
    }

    // Helper method to get the index offset in angle brackets, at which type or const arguments
    // start appearing
    fn get_lifetime_args_offset(&self) -> usize {
        match self.gen_args_info {
            MissingLifetimes { .. } | ExcessLifetimes { .. } => 0,
            MissingTypesOrConsts { args_offset, .. } | ExcessTypesOrConsts { args_offset, .. } => {
                args_offset
            }
        }
    }

    fn get_num_default_params(&self) -> usize {
        match self.gen_args_info {
            MissingTypesOrConsts { num_default_params, .. }
            | ExcessTypesOrConsts { num_default_params, .. } => num_default_params,
            _ => 0,
        }
    }

    fn is_synth_provided(&self) -> bool {
        match self.gen_args_info {
            ExcessTypesOrConsts { synth_provided, .. } => synth_provided,
            _ => false,
        }
    }

    // Helper function to choose a quantifier word for the number of expected arguments
    // and to give a bound for the number of expected arguments
    fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
        if self.get_num_default_params() == 0 {
            match self.gen_args_info {
                MissingLifetimes { .. } | ExcessLifetimes { .. } => {
                    ("", self.num_expected_lifetime_args())
                }
                MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => {
                    ("", self.num_expected_type_or_const_args())
                }
            }
        } else {
            match self.gen_args_info {
                MissingLifetimes { .. } => ("at least ", self.num_expected_lifetime_args()),
                MissingTypesOrConsts { .. } => {
                    ("at least ", self.num_expected_type_or_const_args_including_defaults())
                }
                ExcessLifetimes { .. } => ("at most ", self.num_expected_lifetime_args()),
                ExcessTypesOrConsts { .. } => ("at most ", self.num_expected_type_or_const_args()),
            }
        }
    }

    // Creates lifetime name suggestions from the lifetime parameter names
    fn get_lifetime_args_suggestions_from_param_names(
        &self,
        path_hir_id: hir::HirId,
        num_params_to_take: usize,
    ) -> String {
        debug!(?path_hir_id);

        // If there was already a lifetime among the arguments, just replicate that one.
        if let Some(lt) = self.gen_args.args.iter().find_map(|arg| match arg {
            hir::GenericArg::Lifetime(lt) => Some(lt),
            _ => None,
        }) {
            return std::iter::repeat(lt.to_string())
                .take(num_params_to_take)
                .collect::<Vec<_>>()
                .join(", ");
        }

        let mut ret = Vec::new();
        let mut ty_id = None;
        for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
            debug!(?id);
            if let hir::Node::Ty(_) = node {
                ty_id = Some(id);
            }

            // Suggest `'_` when in function parameter or elided function return.
            if let Some(fn_decl) = node.fn_decl()
                && let Some(ty_id) = ty_id
            {
                let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id);
                let in_ret =
                    matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);

                if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) {
                    return std::iter::repeat("'_".to_owned())
                        .take(num_params_to_take)
                        .collect::<Vec<_>>()
                        .join(", ");
                }
            }

            // Suggest `'static` when in const/static item-like.
            if let hir::Node::Item(hir::Item {
                kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
                ..
            })
            | hir::Node::TraitItem(hir::TraitItem {
                kind: hir::TraitItemKind::Const { .. },
                ..
            })
            | hir::Node::ImplItem(hir::ImplItem {
                kind: hir::ImplItemKind::Const { .. },
                ..
            })
            | hir::Node::ForeignItem(hir::ForeignItem {
                kind: hir::ForeignItemKind::Static { .. },
                ..
            })
            | hir::Node::AnonConst(..) = node
            {
                return std::iter::repeat("'static".to_owned())
                    .take(num_params_to_take.saturating_sub(ret.len()))
                    .collect::<Vec<_>>()
                    .join(", ");
            }

            let params = if let Some(generics) = node.generics() {
                generics.params
            } else if let hir::Node::Ty(ty) = node
                && let hir::TyKind::BareFn(bare_fn) = ty.kind
            {
                bare_fn.generic_params
            } else {
                &[]
            };
            ret.extend(params.iter().filter_map(|p| {
                let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } =
                    p.kind
                else {
                    return None;
                };
                let hir::ParamName::Plain(name) = p.name else { return None };
                Some(name.to_string())
            }));

            if ret.len() >= num_params_to_take {
                return ret[..num_params_to_take].join(", ");
            }
            // We cannot refer to lifetimes defined in an outer function.
            if let hir::Node::Item(_) = node {
                break;
            }
        }

        // We could not gather enough lifetime parameters in the scope.
        // We use the parameter names from the target type's definition instead.
        self.gen_params
            .params
            .iter()
            .skip(self.params_offset + self.num_provided_lifetime_args())
            .take(num_params_to_take)
            .map(|param| param.name.to_string())
            .collect::<Vec<_>>()
            .join(", ")
    }

    // Creates type or constant name suggestions from the provided parameter names
    fn get_type_or_const_args_suggestions_from_param_names(
        &self,
        num_params_to_take: usize,
    ) -> String {
        let is_in_a_method_call = self
            .tcx
            .hir()
            .parent_iter(self.path_segment.hir_id)
            .skip(1)
            .find_map(|(_, node)| match node {
                hir::Node::Expr(expr) => Some(expr),
                _ => None,
            })
            .is_some_and(|expr| {
                matches!(
                    expr.kind,
                    hir::ExprKind::MethodCall(hir::PathSegment { args: Some(_), .. }, ..)
                )
            });

        let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(hir::Node::fn_sig);
        let is_used_in_input = |def_id| {
            fn_sig.is_some_and(|fn_sig| {
                fn_sig.decl.inputs.iter().any(|ty| match ty.kind {
                    hir::TyKind::Path(hir::QPath::Resolved(
                        None,
                        hir::Path { res: hir::def::Res::Def(_, id), .. },
                    )) => *id == def_id,
                    _ => false,
                })
            })
        };
        self.gen_params
            .params
            .iter()
            .skip(self.params_offset + self.num_provided_type_or_const_args())
            .take(num_params_to_take)
            .map(|param| match param.kind {
                // If it's in method call (turbofish), it might be inferred from the expression (e.g. `.collect::<Vec<_>>()`)
                // If it is being inferred from the item's inputs, no need to set it.
                ty::GenericParamDefKind::Type { .. }
                    if is_in_a_method_call || is_used_in_input(param.def_id) =>
                {
                    "_"
                }
                _ => param.name.as_str(),
            })
            .intersperse(", ")
            .collect()
    }

    fn get_unbound_associated_types(&self) -> Vec<String> {
        if self.tcx.is_trait(self.def_id) {
            let items: &AssocItems = self.tcx.associated_items(self.def_id);
            items
                .in_definition_order()
                .filter(|item| item.kind == AssocKind::Type)
                .filter(|item| {
                    !self.gen_args.bindings.iter().any(|binding| binding.ident.name == item.name)
                })
                .map(|item| item.name.to_ident_string())
                .collect()
        } else {
            Vec::default()
        }
    }

    fn create_error_message(&self) -> String {
        let def_path = self.tcx.def_path_str(self.def_id);
        let def_kind = self.tcx.def_descr(self.def_id);
        let (quantifier, bound) = self.get_quantifier_and_bound();
        let kind = self.kind();
        let provided_lt_args = self.num_provided_lifetime_args();
        let provided_type_or_const_args = self.num_provided_type_or_const_args();

        let (provided_args_str, verb) = match self.gen_args_info {
            MissingLifetimes { .. } | ExcessLifetimes { .. } => (
                format!("{} lifetime argument{}", provided_lt_args, pluralize!(provided_lt_args)),
                pluralize!("was", provided_lt_args),
            ),
            MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => (
                format!(
                    "{} generic argument{}",
                    provided_type_or_const_args,
                    pluralize!(provided_type_or_const_args)
                ),
                pluralize!("was", provided_type_or_const_args),
            ),
        };

        if self.gen_args.span_ext().is_some() {
            format!(
                "{} takes {}{} {} argument{} but {} {} supplied",
                def_kind,
                quantifier,
                bound,
                kind,
                pluralize!(bound),
                provided_args_str.as_str(),
                verb
            )
        } else {
            format!("missing generics for {def_kind} `{def_path}`")
        }
    }

    fn start_diagnostics(&self) -> Diag<'tcx> {
        let span = self.path_segment.ident.span;
        let msg = self.create_error_message();
        self.tcx.dcx().struct_span_err(span, msg).with_code(self.code())
    }

    /// Builds the `expected 1 type argument / supplied 2 type arguments` message.
    fn notify(&self, err: &mut Diag<'_>) {
        let (quantifier, bound) = self.get_quantifier_and_bound();
        let provided_args = self.num_provided_args();

        err.span_label(
            self.path_segment.ident.span,
            format!(
                "expected {}{} {} argument{}",
                quantifier,
                bound,
                self.kind(),
                pluralize!(bound),
            ),
        );

        // When too many arguments were provided, we don't highlight each of them, because it
        // would overlap with the suggestion to remove them:
        //
        // ```
        // type Foo = Bar<usize, usize>;
        //                -----  ----- supplied 2 type arguments
        //                     ^^^^^^^ remove this type argument
        // ```
        if self.too_many_args_provided() {
            return;
        }

        let args = self
            .gen_args
            .args
            .iter()
            .skip(self.get_lifetime_args_offset())
            .take(provided_args)
            .enumerate();

        for (i, arg) in args {
            err.span_label(
                arg.span(),
                if i + 1 == provided_args {
                    format!(
                        "supplied {} {} argument{}",
                        provided_args,
                        self.kind(),
                        pluralize!(provided_args)
                    )
                } else {
                    String::new()
                },
            );
        }
    }

    fn suggest(&self, err: &mut Diag<'_>) {
        debug!(
            "suggest(self.provided {:?}, self.gen_args.span(): {:?})",
            self.num_provided_args(),
            self.gen_args.span(),
        );

        match self.angle_brackets {
            AngleBrackets::Missing | AngleBrackets::Implied => self.suggest_adding_args(err),
            AngleBrackets::Available => {
                if self.not_enough_args_provided() {
                    self.suggest_adding_args(err);
                } else if self.too_many_args_provided() {
                    self.suggest_moving_args_from_assoc_fn_to_trait(err);
                    self.suggest_removing_args_or_generics(err);
                } else {
                    unreachable!();
                }
            }
        }
    }

    /// Suggests to add missing argument(s) when current invocation site already contains some
    /// generics:
    ///
    /// ```text
    /// type Map = HashMap<String>;
    /// ```
    fn suggest_adding_args(&self, err: &mut Diag<'_>) {
        if self.gen_args.parenthesized != hir::GenericArgsParentheses::No {
            return;
        }

        match self.gen_args_info {
            MissingLifetimes { .. } => {
                self.suggest_adding_lifetime_args(err);
            }
            MissingTypesOrConsts { .. } => {
                self.suggest_adding_type_and_const_args(err);
            }
            ExcessTypesOrConsts { .. } => {
                // this can happen with `~const T` where T isn't a const_trait.
            }
            _ => unreachable!(),
        }
    }

    fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_>) {
        debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
        let num_missing_args = self.num_missing_lifetime_args();
        let num_params_to_take = num_missing_args;
        let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));

        let suggested_args = self.get_lifetime_args_suggestions_from_param_names(
            self.path_segment.hir_id,
            num_params_to_take,
        );
        debug!("suggested_args: {:?}", &suggested_args);

        match self.angle_brackets {
            AngleBrackets::Missing => {
                let span = self.path_segment.ident.span;

                // insert a suggestion of the form "Y<'a, 'b>"
                let sugg = format!("<{suggested_args}>");
                debug!("sugg: {:?}", sugg);

                err.span_suggestion_verbose(
                    span.shrink_to_hi(),
                    msg,
                    sugg,
                    Applicability::HasPlaceholders,
                );
            }

            AngleBrackets::Available => {
                let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 {
                    (self.gen_args.span().unwrap().shrink_to_lo(), true)
                } else {
                    let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1];
                    (last_lt.span().shrink_to_hi(), false)
                };
                let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
                let has_bindings = !self.gen_args.bindings.is_empty();

                let sugg_prefix = if is_first { "" } else { ", " };
                let sugg_suffix =
                    if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" };

                let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
                debug!("sugg: {:?}", sugg);

                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
            }
            AngleBrackets::Implied => {
                // We never encounter missing lifetimes in situations in which lifetimes are elided
                unreachable!();
            }
        }
    }

    fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_>) {
        let num_missing_args = self.num_missing_type_or_const_args();
        let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));

        let suggested_args =
            self.get_type_or_const_args_suggestions_from_param_names(num_missing_args);
        debug!("suggested_args: {:?}", suggested_args);

        match self.angle_brackets {
            AngleBrackets::Missing | AngleBrackets::Implied => {
                let span = self.path_segment.ident.span;

                // insert a suggestion of the form "Y<T, U>"
                let sugg = format!("<{suggested_args}>");
                debug!("sugg: {:?}", sugg);

                err.span_suggestion_verbose(
                    span.shrink_to_hi(),
                    msg,
                    sugg,
                    Applicability::HasPlaceholders,
                );
            }
            AngleBrackets::Available => {
                let gen_args_span = self.gen_args.span().unwrap();
                let sugg_offset =
                    self.get_lifetime_args_offset() + self.num_provided_type_or_const_args();

                let (sugg_span, is_first) = if sugg_offset == 0 {
                    (gen_args_span.shrink_to_lo(), true)
                } else {
                    let arg_span = self.gen_args.args[sugg_offset - 1].span();
                    // If we came here then inferred lifetime's spans can only point
                    // to either the opening bracket or to the space right after.
                    // Both of these spans have an `hi` lower than or equal to the span
                    // of the generics excluding the brackets.
                    // This allows us to check if `arg_span` is the artificial span of
                    // an inferred lifetime, in which case the generic we're suggesting to
                    // add will be the first visible, even if it isn't the actual first generic.
                    (arg_span.shrink_to_hi(), arg_span.hi() <= gen_args_span.lo())
                };

                let sugg_prefix = if is_first { "" } else { ", " };
                let sugg_suffix =
                    if is_first && !self.gen_args.bindings.is_empty() { ", " } else { "" };

                let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
                debug!("sugg: {:?}", sugg);

                err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders);
            }
        }
    }

    /// Suggests moving redundant argument(s) of an associate function to the
    /// trait it belongs to.
    ///
    /// ```compile_fail
    /// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
    /// ```
    fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diag<'_>) {
        let trait_ = match self.tcx.trait_of_item(self.def_id) {
            Some(def_id) => def_id,
            None => return,
        };

        // Skip suggestion when the associated function is itself generic, it is unclear
        // how to split the provided parameters between those to suggest to the trait and
        // those to remain on the associated type.
        let num_assoc_fn_expected_args =
            self.num_expected_type_or_const_args() + self.num_expected_lifetime_args();
        if num_assoc_fn_expected_args > 0 {
            return;
        }

        let num_assoc_fn_excess_args =
            self.num_excess_type_or_const_args() + self.num_excess_lifetime_args();

        let trait_generics = self.tcx.generics_of(trait_);
        let num_trait_generics_except_self =
            trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };

        let msg = format!(
            "consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
            these = pluralize!("this", num_assoc_fn_excess_args),
            s = pluralize!(num_assoc_fn_excess_args),
            name = self.tcx.item_name(trait_),
            num = num_trait_generics_except_self,
        );

        if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(self.path_segment.hir_id) {
            match &expr.kind {
                hir::ExprKind::Path(qpath) => self
                    .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
                        err,
                        qpath,
                        msg,
                        num_assoc_fn_excess_args,
                        num_trait_generics_except_self,
                    ),
                hir::ExprKind::MethodCall(..) => self
                    .suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
                        err,
                        trait_,
                        expr,
                        msg,
                        num_assoc_fn_excess_args,
                        num_trait_generics_except_self,
                    ),
                _ => return,
            }
        }
    }

    fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
        &self,
        err: &mut Diag<'_>,
        qpath: &'tcx hir::QPath<'tcx>,
        msg: String,
        num_assoc_fn_excess_args: usize,
        num_trait_generics_except_self: usize,
    ) {
        if let hir::QPath::Resolved(_, path) = qpath
            && let Some(trait_path_segment) = path.segments.get(0)
        {
            let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();

            if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args
                == num_trait_generics_except_self
            {
                if let Some(span) = self.gen_args.span_ext()
                    && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
                {
                    let sugg = vec![
                        (
                            self.path_segment.ident.span,
                            format!("{}::{}", snippet, self.path_segment.ident),
                        ),
                        (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
                    ];

                    err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
                }
            }
        }
    }

    fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
        &self,
        err: &mut Diag<'_>,
        trait_def_id: DefId,
        expr: &'tcx hir::Expr<'tcx>,
        msg: String,
        num_assoc_fn_excess_args: usize,
        num_trait_generics_except_self: usize,
    ) {
        let sm = self.tcx.sess.source_map();
        let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else {
            return;
        };
        if num_assoc_fn_excess_args != num_trait_generics_except_self {
            return;
        }
        let Some(gen_args) = self.gen_args.span_ext() else {
            return;
        };
        let Ok(generics) = sm.span_to_snippet(gen_args) else {
            return;
        };
        let Ok(rcvr) =
            sm.span_to_snippet(rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span))
        else {
            return;
        };
        let Ok(rest) = (match args {
            [] => Ok(String::new()),
            [arg] => {
                sm.span_to_snippet(arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span))
            }
            [first, .., last] => {
                let first_span = first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
                let last_span = last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
                sm.span_to_snippet(first_span.to(last_span))
            }
        }) else {
            return;
        };
        let comma = if args.len() > 0 { ", " } else { "" };
        let trait_path = self.tcx.def_path_str(trait_def_id);
        let method_name = self.tcx.item_name(self.def_id);
        err.span_suggestion(
            expr.span,
            msg,
            format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
            Applicability::MaybeIncorrect,
        );
    }

    /// Suggests to remove redundant argument(s):
    ///
    /// ```text
    /// type Map = HashMap<String, String, String, String>;
    /// ```
    fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_>) {
        let num_provided_lt_args = self.num_provided_lifetime_args();
        let num_provided_type_const_args = self.num_provided_type_or_const_args();
        let unbound_types = self.get_unbound_associated_types();
        let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
        assert!(num_provided_args > 0);

        let num_redundant_lt_args = self.num_excess_lifetime_args();
        let num_redundant_type_or_const_args = self.num_excess_type_or_const_args();
        let num_redundant_args = num_redundant_lt_args + num_redundant_type_or_const_args;

        let redundant_lifetime_args = num_redundant_lt_args > 0;
        let redundant_type_or_const_args = num_redundant_type_or_const_args > 0;

        let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
        let provided_args_matches_unbound_traits =
            unbound_types.len() == num_redundant_type_or_const_args;

        let remove_lifetime_args = |err: &mut Diag<'_>| {
            let mut lt_arg_spans = Vec::new();
            let mut found_redundant = false;
            for arg in self.gen_args.args {
                if let hir::GenericArg::Lifetime(_) = arg {
                    lt_arg_spans.push(arg.span());
                    if lt_arg_spans.len() > self.num_expected_lifetime_args() {
                        found_redundant = true;
                    }
                } else if found_redundant {
                    // Argument which is redundant and separated like this `'c`
                    // is not included to avoid including `Bar` in span.
                    // ```
                    // type Foo<'a, T> = &'a T;
                    // let _: Foo<'a, 'b, Bar, 'c>;
                    // ```
                    break;
                }
            }

            let span_lo_redundant_lt_args = lt_arg_spans[self.num_expected_lifetime_args()];
            let span_hi_redundant_lt_args = lt_arg_spans[lt_arg_spans.len() - 1];

            let span_redundant_lt_args = span_lo_redundant_lt_args.to(span_hi_redundant_lt_args);
            debug!("span_redundant_lt_args: {:?}", span_redundant_lt_args);

            let num_redundant_lt_args = lt_arg_spans.len() - self.num_expected_lifetime_args();
            let msg_lifetimes = format!(
                "remove {these} lifetime argument{s}",
                these = pluralize!("this", num_redundant_lt_args),
                s = pluralize!(num_redundant_lt_args),
            );

            err.span_suggestion(
                span_redundant_lt_args,
                msg_lifetimes,
                "",
                Applicability::MaybeIncorrect,
            );
        };

        let remove_type_or_const_args = |err: &mut Diag<'_>| {
            let mut gen_arg_spans = Vec::new();
            let mut found_redundant = false;
            for arg in self.gen_args.args {
                match arg {
                    hir::GenericArg::Type(_)
                    | hir::GenericArg::Const(_)
                    | hir::GenericArg::Infer(_) => {
                        gen_arg_spans.push(arg.span());
                        if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
                            found_redundant = true;
                        }
                    }
                    _ if found_redundant => break,
                    _ => {}
                }
            }

            let span_lo_redundant_type_or_const_args =
                gen_arg_spans[self.num_expected_type_or_const_args()];
            let span_hi_redundant_type_or_const_args = gen_arg_spans[gen_arg_spans.len() - 1];

            let span_redundant_type_or_const_args =
                span_lo_redundant_type_or_const_args.to(span_hi_redundant_type_or_const_args);
            debug!("span_redundant_type_or_const_args: {:?}", span_redundant_type_or_const_args);

            let num_redundant_gen_args =
                gen_arg_spans.len() - self.num_expected_type_or_const_args();
            let msg_types_or_consts = format!(
                "remove {these} generic argument{s}",
                these = pluralize!("this", num_redundant_gen_args),
                s = pluralize!(num_redundant_gen_args),
            );

            err.span_suggestion(
                span_redundant_type_or_const_args,
                msg_types_or_consts,
                "",
                Applicability::MaybeIncorrect,
            );
        };

        // If there is a single unbound associated type and a single excess generic param
        // suggest replacing the generic param with the associated type bound
        if provided_args_matches_unbound_traits && !unbound_types.is_empty() {
            // Don't suggest if we're in a trait impl as
            // that would result in invalid syntax (fixes #116464)
            if !self.is_in_trait_impl() {
                let unused_generics = &self.gen_args.args[self.num_expected_type_or_const_args()..];
                let suggestions = iter::zip(unused_generics, &unbound_types)
                    .map(|(potential, name)| {
                        (potential.span().shrink_to_lo(), format!("{name} = "))
                    })
                    .collect::<Vec<_>>();

                if !suggestions.is_empty() {
                    err.multipart_suggestion_verbose(
                        format!(
                            "replace the generic bound{s} with the associated type{s}",
                            s = pluralize!(unbound_types.len())
                        ),
                        suggestions,
                        Applicability::MaybeIncorrect,
                    );
                }
            }
        } else if remove_entire_generics {
            let span = self
                .path_segment
                .args
                .unwrap()
                .span_ext()
                .unwrap()
                .with_lo(self.path_segment.ident.span.hi());

            let msg = format!(
                "remove these {}generics",
                if self.gen_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
                    "parenthetical "
                } else {
                    ""
                },
            );

            err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
        } else if redundant_lifetime_args && redundant_type_or_const_args {
            remove_lifetime_args(err);
            remove_type_or_const_args(err);
        } else if redundant_lifetime_args {
            remove_lifetime_args(err);
        } else {
            assert!(redundant_type_or_const_args);
            remove_type_or_const_args(err);
        }
    }

    /// Builds the `type defined here` message.
    fn show_definition(&self, err: &mut Diag<'_>) {
        let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) {
            if self.tcx.sess.source_map().is_span_accessible(def_span) {
                def_span.into()
            } else {
                return;
            }
        } else {
            return;
        };

        let msg = {
            let def_kind = self.tcx.def_descr(self.def_id);
            let (quantifier, bound) = self.get_quantifier_and_bound();

            let params = if bound == 0 {
                String::new()
            } else {
                let params = self
                    .gen_params
                    .params
                    .iter()
                    .skip(self.params_offset)
                    .take(bound)
                    .map(|param| {
                        let span = self.tcx.def_span(param.def_id);
                        spans.push_span_label(span, "");
                        param
                    })
                    .map(|param| format!("`{}`", param.name))
                    .collect::<Vec<_>>()
                    .join(", ");

                format!(": {params}")
            };

            format!(
                "{} defined here, with {}{} {} parameter{}{}",
                def_kind,
                quantifier,
                bound,
                self.kind(),
                pluralize!(bound),
                params,
            )
        };

        err.span_note(spans, msg);
    }

    /// Add note if `impl Trait` is explicitly specified.
    fn note_synth_provided(&self, err: &mut Diag<'_>) {
        if !self.is_synth_provided() {
            return;
        }

        err.note("`impl Trait` cannot be explicitly specified as a generic argument");
    }
}

impl<'tcx> StructuredDiag<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
    fn session(&self) -> &Session {
        self.tcx.sess
    }

    fn code(&self) -> ErrCode {
        E0107
    }

    fn diagnostic_common(&self) -> Diag<'tcx> {
        let mut err = self.start_diagnostics();

        self.notify(&mut err);
        self.suggest(&mut err);
        self.show_definition(&mut err);
        self.note_synth_provided(&mut err);

        err
    }
}
