use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeQPath;
use clippy_utils::{expr_or_init, fn_def_id_with_node_args, sym};
use rustc_ast::BinOpKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{FnKind, Visitor, walk_body, walk_expr};
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
use rustc_hir_analysis::lower_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use rustc_span::symbol::{Ident, kw};
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
use std::ops::ControlFlow;

declare_clippy_lint! {
    /// ### What it does
    /// Checks that there isn't an infinite recursion in trait
    /// implementations.
    ///
    /// ### Why is this bad?
    /// Infinite recursion in trait implementation will either cause crashes
    /// or result in an infinite loop, and it is hard to detect.
    ///
    /// ### Example
    /// ```no_run
    /// enum Foo {
    ///     A,
    ///     B,
    /// }
    ///
    /// impl PartialEq for Foo {
    ///     fn eq(&self, other: &Self) -> bool {
    ///         self == other // bad!
    ///     }
    /// }
    /// ```
    ///
    /// Use instead:
    ///
    /// ```no_run
    /// #[derive(PartialEq)]
    /// enum Foo {
    ///     A,
    ///     B,
    /// }
    /// ```
    ///
    /// As an alternative, rewrite the logic without recursion:
    ///
    /// ```no_run
    /// enum Foo {
    ///     A,
    ///     B,
    /// }
    ///
    /// impl PartialEq for Foo {
    ///     fn eq(&self, other: &Self) -> bool {
    ///         matches!((self, other), (Foo::A, Foo::A) | (Foo::B, Foo::B))
    ///     }
    /// }
    /// ```
    #[clippy::version = "1.77.0"]
    pub UNCONDITIONAL_RECURSION,
    suspicious,
    "detect unconditional recursion in some traits implementation"
}

impl_lint_pass!(UnconditionalRecursion => [UNCONDITIONAL_RECURSION]);

#[derive(Default)]
pub struct UnconditionalRecursion {
    /// The key is the `DefId` of the type implementing the `Default` trait and the value is the
    /// `DefId` of the return call.
    default_impl_for_type: FxHashMap<DefId, DefId>,
}

fn span_error(cx: &LateContext<'_>, method_span: Span, expr: &Expr<'_>) {
    span_lint_and_then(
        cx,
        UNCONDITIONAL_RECURSION,
        method_span,
        "function cannot return without recursing",
        |diag| {
            diag.span_note(expr.span, "recursive call site");
        },
    );
}

fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option<DefId> {
    let TyKind::Path(qpath) = hir_ty.kind else { return None };
    match qpath {
        QPath::Resolved(_, path) => path.res.opt_def_id(),
        QPath::TypeRelative(_, _) => {
            let ty = lower_ty(tcx, &hir_ty);

            match ty.kind() {
                ty::Alias(
                    _,
                    proj @ ty::AliasTy {
                        kind: ty::Projection { .. },
                        ..
                    },
                ) => Res::<HirId>::Def(DefKind::Trait, proj.trait_ref(tcx).def_id).opt_def_id(),
                _ => None,
            }
        },
    }
}

fn get_return_calls_in_body<'tcx>(body: &'tcx Body<'tcx>) -> Vec<&'tcx Expr<'tcx>> {
    let mut visitor = ReturnsVisitor::default();

    visitor.visit_body(body);
    visitor.returns
}

fn has_conditional_return(body: &Body<'_>, expr: &Expr<'_>) -> bool {
    match get_return_calls_in_body(body).as_slice() {
        [] => false,
        [return_expr] => return_expr.hir_id != expr.hir_id,
        _ => true,
    }
}

fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Option<DefId> {
    let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id);
    if let Some((
        _,
        Node::Item(Item {
            kind: ItemKind::Impl(impl_),
            owner_id,
            ..
        }),
    )) = cx.tcx.hir_parent_iter(hir_id).next()
        // We exclude `impl` blocks generated from rustc's proc macros.
        && !cx.tcx.is_automatically_derived(owner_id.to_def_id())
        // It is a implementation of a trait.
        && let Some(of_trait) = impl_.of_trait
    {
        of_trait.trait_ref.trait_def_id()
    } else {
        None
    }
}

/// When we have `x == y` where `x = &T` and `y = &T`, then that resolves to
/// `<&T as PartialEq<&T>>::eq`, which is not the same as `<T as PartialEq<T>>::eq`,
/// however we still would want to treat it the same, because we know that it's a blanket impl
/// that simply delegates to the `PartialEq` impl with one reference removed.
///
/// Still, we can't just do `lty.peel_refs() == rty.peel_refs()` because when we have `x = &T` and
/// `y = &&T`, this is not necessarily the same as `<T as PartialEq<T>>::eq`
///
/// So to avoid these FNs and FPs, we keep removing a layer of references from *both* sides
/// until both sides match the expected LHS and RHS type (or they don't).
fn matches_ty<'tcx>(
    mut left: Ty<'tcx>,
    mut right: Ty<'tcx>,
    expected_left: Ty<'tcx>,
    expected_right: Ty<'tcx>,
) -> bool {
    while let (&ty::Ref(_, lty, _), &ty::Ref(_, rty, _)) = (left.kind(), right.kind()) {
        if lty == expected_left && rty == expected_right {
            return true;
        }
        left = lty;
        right = rty;
    }
    false
}

fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {
    let Some(sig) = cx
        .typeck_results()
        .liberated_fn_sigs()
        .get(cx.tcx.local_def_id_to_hir_id(method_def_id))
    else {
        return;
    };

    // That has two arguments.
    if let [self_arg, other_arg] = sig.inputs()
        && let &ty::Ref(_, self_arg, _) = self_arg.kind()
        && let &ty::Ref(_, other_arg, _) = other_arg.kind()
        // The two arguments are of the same type.
        && let Some(trait_def_id) = get_impl_trait_def_id(cx, method_def_id)
        // The trait is `PartialEq`.
        && cx.tcx.is_diagnostic_item(sym::PartialEq, trait_def_id)
    {
        let to_check_op = if name.name == sym::eq {
            BinOpKind::Eq
        } else {
            BinOpKind::Ne
        };
        let is_bad = match expr.kind {
            ExprKind::Binary(op, left, right) if op.node == to_check_op => {
                // Then we check if the LHS matches self_arg and RHS matches other_arg
                let left_ty = cx.typeck_results().expr_ty_adjusted(left);
                let right_ty = cx.typeck_results().expr_ty_adjusted(right);
                matches_ty(left_ty, right_ty, self_arg, other_arg)
            },
            ExprKind::MethodCall(segment, receiver, [arg], _) if segment.ident.name == name.name => {
                let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver);
                let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);

                if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
                    && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)
                    && trait_id == trait_def_id
                    && matches_ty(receiver_ty, arg_ty, self_arg, other_arg)
                {
                    true
                } else {
                    false
                }
            },
            _ => false,
        };
        if is_bad {
            span_error(cx, method_span, expr);
        }
    }
}

fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {
    let args = cx
        .tcx
        .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(method_def_id).skip_binder())
        .inputs();
    // That has one argument.
    if let [_self_arg] = args
        && let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id)
        && let Some((
            _,
            Node::Item(Item {
                kind: ItemKind::Impl(impl_),
                owner_id,
                ..
            }),
        )) = cx.tcx.hir_parent_iter(hir_id).next()
        // We exclude `impl` blocks generated from rustc's proc macros.
        && !cx.tcx.is_automatically_derived(owner_id.to_def_id())
        // It is a implementation of a trait.
        && let Some(of_trait) = impl_.of_trait
        && let Some(trait_def_id) = of_trait.trait_ref.trait_def_id()
        // The trait is `ToString`.
        && cx.tcx.is_diagnostic_item(sym::ToString, trait_def_id)
    {
        let is_bad = match expr.kind {
            ExprKind::MethodCall(segment, _receiver, &[_arg], _) if segment.ident.name == name.name => {
                if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
                    && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)
                    && trait_id == trait_def_id
                {
                    true
                } else {
                    false
                }
            },
            _ => false,
        };
        if is_bad {
            span_error(cx, method_span, expr);
        }
    }
}

fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, implemented_ty_id: DefId) -> bool {
    match qpath {
        QPath::Resolved(_, path) => match path.segments {
            [first, .., last] => last.ident.name == kw::Default && first.res.opt_def_id() == Some(implemented_ty_id),
            _ => false,
        },
        QPath::TypeRelative(ty, segment) => {
            if segment.ident.name != kw::Default {
                return false;
            }
            if matches!(
                ty.kind,
                TyKind::Path(QPath::Resolved(
                    _,
                    hir::Path {
                        res: Res::SelfTyAlias { .. },
                        ..
                    },
                ))
            ) {
                return true;
            }
            get_hir_ty_def_id(tcx, *ty) == Some(implemented_ty_id)
        },
    }
}

struct CheckCalls<'a, 'tcx> {
    cx: &'a LateContext<'tcx>,
    implemented_ty_id: DefId,
    method_span: Span,
}

impl<'a, 'tcx> Visitor<'tcx> for CheckCalls<'a, 'tcx>
where
    'tcx: 'a,
{
    type NestedFilter = nested_filter::OnlyBodies;
    type Result = ControlFlow<()>;

    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
        self.cx.tcx
    }

    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
        walk_expr(self, expr)?;

        if let ExprKind::Call(f, _) = expr.kind
            && let ExprKind::Path(qpath) = f.kind
            && is_default_method_on_current_ty(self.cx.tcx, qpath, self.implemented_ty_id)
            && let Some(method_def_id) = f.res(self.cx).opt_def_id()
            && let Some(trait_def_id) = self.cx.tcx.trait_of_assoc(method_def_id)
            && self.cx.tcx.is_diagnostic_item(sym::Default, trait_def_id)
        {
            span_error(self.cx, self.method_span, expr);
            return ControlFlow::Break(());
        }
        ControlFlow::Continue(())
    }
}

impl UnconditionalRecursion {
    fn init_default_impl_for_type_if_needed(&mut self, cx: &LateContext<'_>) {
        if self.default_impl_for_type.is_empty()
            && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
        {
            let impls = cx.tcx.trait_impls_of(default_trait_id);
            for (ty, impl_def_ids) in impls.non_blanket_impls() {
                let Some(self_def_id) = ty.def() else { continue };
                for &impl_def_id in impl_def_ids {
                    if !cx.tcx.is_automatically_derived(impl_def_id) &&
                        let Some(assoc_item) = cx
                            .tcx
                            .associated_items(impl_def_id)
                            .in_definition_order()
                            // We're not interested in foreign implementations of the `Default` trait.
                            .find(|item| {
                                item.is_fn() && item.def_id.is_local() && item.name() == kw::Default
                            })
                        && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id)
                        && let Some(body_id) = body_node.body_id()
                        && let body = cx.tcx.hir_body(body_id)
                        // We don't want to keep it if it has conditional return.
                        && let [return_expr] = get_return_calls_in_body(body).as_slice()
                        && let ExprKind::Call(call_expr, _) = return_expr.kind
                        // We need to use typeck here to infer the actual function being called.
                        && let body_def_id = cx.tcx.hir_enclosing_body_owner(call_expr.hir_id)
                        && let Some(body_owner) = cx.tcx.hir_maybe_body_owned_by(body_def_id)
                        && let typeck = cx.tcx.typeck_body(body_owner.id())
                        && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id)
                    {
                        self.default_impl_for_type.insert(self_def_id, call_def_id);
                    }
                }
            }
        }
    }

    fn check_default_new<'tcx>(
        &mut self,
        cx: &LateContext<'tcx>,
        decl: &FnDecl<'tcx>,
        body: &'tcx Body<'tcx>,
        method_span: Span,
        method_def_id: LocalDefId,
    ) {
        // We're only interested into static methods.
        if decl.implicit_self().has_implicit_self() {
            return;
        }
        // We don't check trait implementations.
        if get_impl_trait_def_id(cx, method_def_id).is_some() {
            return;
        }

        let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id);
        if let Some((
            _,
            Node::Item(Item {
                kind: ItemKind::Impl(impl_),
                ..
            }),
        )) = cx.tcx.hir_parent_iter(hir_id).next()
            && let Some(implemented_ty_id) = get_hir_ty_def_id(cx.tcx, *impl_.self_ty)
            && {
                self.init_default_impl_for_type_if_needed(cx);
                true
            }
            && let Some(return_def_id) = self.default_impl_for_type.get(&implemented_ty_id)
            && method_def_id.to_def_id() == *return_def_id
        {
            let mut c = CheckCalls {
                cx,
                implemented_ty_id,
                method_span,
            };
            let _ = walk_body(&mut c, body);
        }
    }
}

fn check_from(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, expr: &Expr<'_>) {
    let Some(sig) = cx
        .typeck_results()
        .liberated_fn_sigs()
        .get(cx.tcx.local_def_id_to_hir_id(method_def_id))
    else {
        return;
    };

    // Check if we are calling `Into::into` where the node args match with our `From::from` signature:
    // From::from signature: fn(S1) -> S2
    // <S1 as Into<S2>>::into(s1), node_args=[S1, S2]
    // If they do match, then it must mean that it is the blanket impl,
    // which calls back into our `From::from` again (`Into` is not specializable).
    // rustc's unconditional_recursion already catches calling `From::from` directly
    if let Some((fn_def_id, node_args)) = fn_def_id_with_node_args(cx, expr)
        && let [s1, s2] = **node_args
        && let (Some(s1), Some(s2)) = (s1.as_type(), s2.as_type())
        && let Some(trait_def_id) = cx.tcx.trait_of_assoc(fn_def_id)
        && cx.tcx.is_diagnostic_item(sym::Into, trait_def_id)
        && get_impl_trait_def_id(cx, method_def_id) == cx.tcx.get_diagnostic_item(sym::From)
        && s1 == sig.inputs()[0]
        && s2 == sig.output()
    {
        span_error(cx, method_span, expr);
    }
}

impl<'tcx> LateLintPass<'tcx> for UnconditionalRecursion {
    fn check_fn(
        &mut self,
        cx: &LateContext<'tcx>,
        kind: FnKind<'tcx>,
        decl: &'tcx FnDecl<'tcx>,
        body: &'tcx Body<'tcx>,
        method_span: Span,
        method_def_id: LocalDefId,
    ) {
        // If the function is a method...
        if let FnKind::Method(name, _) = kind
            && let expr = expr_or_init(cx, body.value).peel_blocks()
            // Doesn't have a conditional return.
            && !has_conditional_return(body, expr)
        {
            match name.name {
                sym::eq | sym::ne => check_partial_eq(cx, method_span, method_def_id, name, expr),
                sym::to_string => check_to_string(cx, method_span, method_def_id, name, expr),
                sym::from => check_from(cx, method_span, method_def_id, expr),
                _ => {},
            }
            self.check_default_new(cx, decl, body, method_span, method_def_id);
        }
    }
}
