use crate::{
    method::probe::{self, Pick},
    FnCtxt,
};
use hir::def_id::DefId;
use hir::HirId;
use hir::ItemKind;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_infer::infer::type_variable::TypeVariableOrigin;
use rustc_middle::ty::{self, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::{Empty, Underscore};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
use std::fmt::Write;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    pub(super) fn lint_dot_call_from_2018(
        &self,
        self_ty: Ty<'tcx>,
        segment: &hir::PathSegment<'_>,
        span: Span,
        call_expr: &'tcx hir::Expr<'tcx>,
        self_expr: &'tcx hir::Expr<'tcx>,
        pick: &Pick<'tcx>,
        args: &'tcx [hir::Expr<'tcx>],
    ) {
        debug!(
            "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
            segment.ident, self_ty, call_expr, self_expr
        );

        // Rust 2021 and later is already using the new prelude
        if span.at_least_rust_2021() {
            return;
        }

        let prelude_or_array_lint = match segment.ident.name {
            // `try_into` was added to the prelude in Rust 2021.
            sym::try_into => RUST_2021_PRELUDE_COLLISIONS,
            // `into_iter` wasn't added to the prelude,
            // but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
            // before Rust 2021, which results in the same problem.
            // It is only a problem for arrays.
            sym::into_iter if let ty::Array(..) = self_ty.kind() => {
                // In this case, it wasn't really a prelude addition that was the problem.
                // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021.
                rustc_lint::ARRAY_INTO_ITER
            }
            _ => return,
        };

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick) {
            // avoid repeatedly adding unneeded `&*`s
            if pick.autoderefs == 1
                && matches!(
                    pick.autoref_or_ptr_adjustment,
                    Some(probe::AutorefOrPtrAdjustment::Autoref { .. })
                )
                && matches!(self_ty.kind(), ty::Ref(..))
            {
                return;
            }

            // if it's an inherent `self` method (not `&self` or `&mut self`), it will take
            // precedence over the `TryInto` impl, and thus won't break in 2021 edition
            if pick.autoderefs == 0 && pick.autoref_or_ptr_adjustment.is_none() {
                return;
            }

            // Inherent impls only require not relying on autoref and autoderef in order to
            // ensure that the trait implementation won't be used
            self.tcx.node_span_lint(
                prelude_or_array_lint,
                self_expr.hir_id,
                self_expr.span,
                format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
                |lint| {
                    let sp = self_expr.span;

                    let derefs = "*".repeat(pick.autoderefs);

                    let autoref = match pick.autoref_or_ptr_adjustment {
                        Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => {
                            mutbl.ref_prefix_str()
                        }
                        Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
                    };
                    if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span)
                    {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{derefs}{self_expr} as *const _")
                        } else {
                            format!("{autoref}{derefs}{self_expr}")
                        };

                        lint.span_suggestion(
                            sp,
                            "disambiguate the method call",
                            format!("({self_adjusted})"),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{derefs}(...) as *const _")
                        } else {
                            format!("{autoref}{derefs}...")
                        };
                        lint.span_help(
                            sp,
                            format!("disambiguate the method call with `({self_adjusted})`",),
                        );
                    }
                },
            );
        } else {
            // trait implementations require full disambiguation to not clash with the new prelude
            // additions (i.e. convert from dot-call to fully-qualified call)
            self.tcx.node_span_lint(
                prelude_or_array_lint,
                call_expr.hir_id,
                call_expr.span,
                format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
                |lint| {
                    let sp = call_expr.span;
                    let trait_name = self.trait_path_or_bare_name(
                        span,
                        call_expr.hir_id,
                        pick.item.container_id(self.tcx),
                    );

                    let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp);
                    if precise {
                        let args = args.iter().fold(String::new(), |mut string, arg| {
                            let span = arg.span.find_ancestor_inside(sp).unwrap_or_default();
                            write!(
                                string,
                                ", {}",
                                self.sess().source_map().span_to_snippet(span).unwrap()
                            )
                            .unwrap();
                            string
                        });

                        lint.span_suggestion(
                            sp,
                            "disambiguate the associated function",
                            format!(
                                "{}::{}{}({}{})",
                                trait_name,
                                segment.ident.name,
                                if let Some(args) = segment.args.as_ref().and_then(|args| self
                                    .sess()
                                    .source_map()
                                    .span_to_snippet(args.span_ext)
                                    .ok())
                                {
                                    // Keep turbofish.
                                    format!("::{args}")
                                } else {
                                    String::new()
                                },
                                self_adjusted,
                                args,
                            ),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        lint.span_help(
                            sp,
                            format!(
                                "disambiguate the associated function with `{}::{}(...)`",
                                trait_name, segment.ident,
                            ),
                        );
                    }
                },
            );
        }
    }

    pub(super) fn lint_fully_qualified_call_from_2018(
        &self,
        span: Span,
        method_name: Ident,
        self_ty: Ty<'tcx>,
        self_ty_span: Span,
        expr_id: hir::HirId,
        pick: &Pick<'tcx>,
    ) {
        // Rust 2021 and later is already using the new prelude
        if span.at_least_rust_2021() {
            return;
        }

        // These are the fully qualified methods added to prelude in Rust 2021
        if !matches!(method_name.name, sym::try_into | sym::try_from | sym::from_iter) {
            return;
        }

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        // For from_iter, check if the type actually implements FromIterator.
        // If we know it does not, we don't need to warn.
        if method_name.name == sym::from_iter {
            if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) {
                let any_type =
                    self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span });
                if !self
                    .infcx
                    .type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env)
                    .may_apply()
                {
                    return;
                }
            }
        }

        // No need to lint if this is an inherent method called on a specific type, like `Vec::foo(...)`,
        // since such methods take precedence over trait methods.
        if matches!(pick.kind, probe::PickKind::InherentImplPick) {
            return;
        }

        self.tcx.node_span_lint(
            RUST_2021_PRELUDE_COLLISIONS,
            expr_id,
            span,
            format!(
                "trait-associated function `{}` will become ambiguous in Rust 2021",
                method_name.name
            ),
            |lint| {
                // "type" refers to either a type or, more likely, a trait from which
                // the associated function or method is from.
                let container_id = pick.item.container_id(self.tcx);
                let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
                let trait_generics = self.tcx.generics_of(container_id);

                let trait_name = if trait_generics.params.len() <= trait_generics.has_self as usize
                {
                    trait_path
                } else {
                    let counts = trait_generics.own_counts();
                    format!(
                        "{}<{}>",
                        trait_path,
                        std::iter::repeat("'_")
                            .take(counts.lifetimes)
                            .chain(std::iter::repeat("_").take(
                                counts.types + counts.consts - trait_generics.has_self as usize
                            ))
                            .collect::<Vec<_>>()
                            .join(", ")
                    )
                };

                let mut self_ty_name = self_ty_span
                    .find_ancestor_inside(span)
                    .and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
                    .unwrap_or_else(|| self_ty.to_string());

                // Get the number of generics the self type has (if an Adt) unless we can determine that
                // the user has written the self type with generics already which we (naively) do by looking
                // for a "<" in `self_ty_name`.
                if !self_ty_name.contains('<') {
                    if let ty::Adt(def, _) = self_ty.kind() {
                        let generics = self.tcx.generics_of(def.did());
                        if !generics.params.is_empty() {
                            let counts = generics.own_counts();
                            self_ty_name += &format!(
                                "<{}>",
                                std::iter::repeat("'_")
                                    .take(counts.lifetimes)
                                    .chain(
                                        std::iter::repeat("_").take(counts.types + counts.consts)
                                    )
                                    .collect::<Vec<_>>()
                                    .join(", ")
                            );
                        }
                    }
                }
                lint.span_suggestion(
                    span,
                    "disambiguate the associated function",
                    format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
                    Applicability::MachineApplicable,
                );
            },
        );
    }

    fn trait_path_or_bare_name(
        &self,
        span: Span,
        expr_hir_id: HirId,
        trait_def_id: DefId,
    ) -> String {
        self.trait_path(span, expr_hir_id, trait_def_id).unwrap_or_else(|| {
            let key = self.tcx.def_key(trait_def_id);
            format!("{}", key.disambiguated_data.data)
        })
    }

    fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Option<String> {
        let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?;
        let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?;
        if applicable_trait.import_ids.is_empty() {
            // The trait was declared within the module, we only need to use its name.
            return None;
        }

        let import_items: Vec<_> = applicable_trait
            .import_ids
            .iter()
            .map(|&import_id| self.tcx.hir().expect_item(import_id))
            .collect();

        // Find an identifier with which this trait was imported (note that `_` doesn't count).
        let any_id = import_items
            .iter()
            .find_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None });
        if let Some(any_id) = any_id {
            if any_id.name == Empty {
                // Glob import, so just use its name.
                return None;
            } else {
                return Some(format!("{any_id}"));
            }
        }

        // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
        // so just take the first one.
        match import_items[0].kind {
            ItemKind::Use(path, _) => Some(
                path.segments
                    .iter()
                    .map(|segment| segment.ident.to_string())
                    .collect::<Vec<_>>()
                    .join("::"),
            ),
            _ => {
                span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind);
            }
        }
    }

    /// Creates a string version of the `expr` that includes explicit adjustments.
    /// Returns the string and also a bool indicating whether this is a *precise*
    /// suggestion.
    fn adjust_expr(
        &self,
        pick: &Pick<'tcx>,
        expr: &hir::Expr<'tcx>,
        outer: Span,
    ) -> (String, bool) {
        let derefs = "*".repeat(pick.autoderefs);

        let autoref = match pick.autoref_or_ptr_adjustment {
            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => mutbl.ref_prefix_str(),
            Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
        };

        let (expr_text, precise) = if let Some(expr_text) = expr
            .span
            .find_ancestor_inside(outer)
            .and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
        {
            (expr_text, true)
        } else {
            ("(..)".to_string(), false)
        };

        let adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
            pick.autoref_or_ptr_adjustment
        {
            format!("{derefs}{expr_text} as *const _")
        } else {
            format!("{autoref}{derefs}{expr_text}")
        };

        (adjusted_text, precise)
    }
}
