use std::iter::repeat_n;
use std::ops::ControlFlow;

use hir::intravisit::{self, Visitor};
use rustc_ast::Recovered;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic, SuggestionStyle};
use rustc_hir::{self as hir, HirIdSet};
use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::significant_drop_order::{
    extract_component_with_significant_dtor, ty_dtor_span,
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint::{FutureIncompatibilityReason, LintId};
use rustc_session::{declare_lint, impl_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::{DUMMY_SP, Span};
use smallvec::SmallVec;

use crate::{LateContext, LateLintPass};

declare_lint! {
    /// The `if_let_rescope` lint detects cases where a temporary value with
    /// significant drop is generated on the right hand side of `if let`
    /// and suggests a rewrite into `match` when possible.
    ///
    /// ### Example
    ///
    /// ```rust,edition2021
    /// #![warn(if_let_rescope)]
    /// #![allow(unused_variables)]
    ///
    /// struct Droppy;
    /// impl Drop for Droppy {
    ///     fn drop(&mut self) {
    ///         // Custom destructor, including this `drop` implementation, is considered
    ///         // significant.
    ///         // Rust does not check whether this destructor emits side-effects that can
    ///         // lead to observable change in program semantics, when the drop order changes.
    ///         // Rust biases to be on the safe side, so that you can apply discretion whether
    ///         // this change indeed breaches any contract or specification that your code needs
    ///         // to honour.
    ///         println!("dropped");
    ///     }
    /// }
    /// impl Droppy {
    ///     fn get(&self) -> Option<u8> {
    ///         None
    ///     }
    /// }
    ///
    /// fn main() {
    ///     if let Some(value) = Droppy.get() {
    ///         // do something
    ///     } else {
    ///         // do something else
    ///     }
    /// }
    /// ```
    ///
    /// {{produces}}
    ///
    /// ### Explanation
    ///
    /// With Edition 2024, temporaries generated while evaluating `if let`s
    /// will be dropped before the `else` block.
    /// This lint captures a possible change in runtime behaviour due to
    /// a change in sequence of calls to significant `Drop::drop` destructors.
    ///
    /// A significant [`Drop::drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html)
    /// destructor here refers to an explicit, arbitrary implementation of the `Drop` trait on the type
    /// with exceptions including `Vec`, `Box`, `Rc`, `BTreeMap` and `HashMap`
    /// that are marked by the compiler otherwise so long that the generic types have
    /// no significant destructor recursively.
    /// In other words, a type has a significant drop destructor when it has a `Drop` implementation
    /// or its destructor invokes a significant destructor on a type.
    /// Since we cannot completely reason about the change by just inspecting the existence of
    /// a significant destructor, this lint remains only a suggestion and is set to `allow` by default.
    ///
    /// Whenever possible, a rewrite into an equivalent `match` expression that
    /// observe the same order of calls to such destructors is proposed by this lint.
    /// Authors may take their own discretion whether the rewrite suggestion shall be
    /// accepted, or rejected to continue the use of the `if let` expression.
    pub IF_LET_RESCOPE,
    Allow,
    "`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and \
    rewriting in `match` is an option to preserve the semantics up to Edition 2021",
    @future_incompatible = FutureIncompatibleInfo {
        reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
        reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>",
    };
}

/// Lint for potential change in program semantics of `if let`s
#[derive(Default)]
pub(crate) struct IfLetRescope {
    skip: HirIdSet,
}

fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
    let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(hir_id).next() else {
        return false;
    };
    let hir::ExprKind::If(_cond, _conseq, Some(alt)) = expr.kind else { return false };
    alt.hir_id == hir_id
}

fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
    let mut parents = tcx.hir_parent_iter(hir_id);
    let stmt = match parents.next() {
        Some((_, hir::Node::Stmt(stmt))) => stmt,
        Some((_, hir::Node::Block(_) | hir::Node::Arm(_))) => return true,
        _ => return false,
    };
    let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = stmt.kind else { return false };
    expr.hir_id == hir_id
}

fn match_head_needs_bracket(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> bool {
    expr_parent_is_else(tcx, expr.hir_id) && matches!(expr.kind, hir::ExprKind::If(..))
}

impl IfLetRescope {
    fn probe_if_cascade<'tcx>(&mut self, cx: &LateContext<'tcx>, mut expr: &'tcx hir::Expr<'tcx>) {
        if self.skip.contains(&expr.hir_id) {
            return;
        }
        let tcx = cx.tcx;
        let source_map = tcx.sess.source_map();
        let expr_end = match expr.kind {
            hir::ExprKind::If(_cond, conseq, None) => conseq.span.shrink_to_hi(),
            hir::ExprKind::If(_cond, _conseq, Some(alt)) => alt.span.shrink_to_hi(),
            _ => return,
        };
        let mut seen_dyn = false;
        let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr);
        let mut significant_droppers = vec![];
        let mut lifetime_ends = vec![];
        let mut closing_brackets = 0;
        let mut alt_heads = vec![];
        let mut match_heads = vec![];
        let mut consequent_heads = vec![];
        let mut destructors = vec![];
        let mut first_if_to_lint = None;
        let mut first_if_to_rewrite = false;
        let mut empty_alt = false;
        while let hir::ExprKind::If(cond, conseq, alt) = expr.kind {
            self.skip.insert(expr.hir_id);
            // We are interested in `let` fragment of the condition.
            // Otherwise, we probe into the `else` fragment.
            if let hir::ExprKind::Let(&hir::LetExpr {
                span,
                pat,
                init,
                ty: ty_ascription,
                recovered: Recovered::No,
            }) = cond.kind
            {
                // Peel off round braces
                let if_let_pat = source_map
                    .span_take_while(expr.span, |&ch| ch == '(' || ch.is_whitespace())
                    .between(init.span);
                // The consequent fragment is always a block.
                let before_conseq = conseq.span.shrink_to_lo();
                let lifetime_end = source_map.end_point(conseq.span);

                if let ControlFlow::Break((drop_span, drop_tys)) =
                    (FindSignificantDropper { cx }).check_if_let_scrutinee(init)
                {
                    destructors.extend(drop_tys.into_iter().filter_map(|ty| {
                        if let Some(span) = ty_dtor_span(tcx, ty) {
                            Some(DestructorLabel { span, dtor_kind: "concrete" })
                        } else if matches!(ty.kind(), ty::Dynamic(..)) {
                            if seen_dyn {
                                None
                            } else {
                                seen_dyn = true;
                                Some(DestructorLabel { span: DUMMY_SP, dtor_kind: "dyn" })
                            }
                        } else {
                            None
                        }
                    }));
                    first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id)));
                    significant_droppers.push(drop_span);
                    lifetime_ends.push(lifetime_end);
                    if ty_ascription.is_some()
                        || !expr.span.can_be_used_for_suggestions()
                        || !pat.span.can_be_used_for_suggestions()
                        || !if_let_pat.can_be_used_for_suggestions()
                        || !before_conseq.can_be_used_for_suggestions()
                    {
                        // Our `match` rewrites does not support type ascription,
                        // so we just bail.
                        // Alternatively when the span comes from proc macro expansion,
                        // we will also bail.
                        // FIXME(#101728): change this when type ascription syntax is stabilized again
                    } else if let Ok(pat) = source_map.span_to_snippet(pat.span) {
                        let emit_suggestion = |alt_span| {
                            first_if_to_rewrite = true;
                            if add_bracket_to_match_head {
                                closing_brackets += 2;
                                match_heads.push(SingleArmMatchBegin::WithOpenBracket(if_let_pat));
                            } else {
                                // Sometimes, wrapping `match` into a block is undesirable,
                                // because the scrutinee temporary lifetime is shortened and
                                // the proposed fix will not work.
                                closing_brackets += 1;
                                match_heads
                                    .push(SingleArmMatchBegin::WithoutOpenBracket(if_let_pat));
                            }
                            consequent_heads.push(ConsequentRewrite { span: before_conseq, pat });
                            if let Some(alt_span) = alt_span {
                                alt_heads.push(AltHead(alt_span));
                            }
                        };
                        if let Some(alt) = alt {
                            let alt_head = conseq.span.between(alt.span);
                            if alt_head.can_be_used_for_suggestions() {
                                // We lint only when the `else` span is user code, too.
                                emit_suggestion(Some(alt_head));
                            }
                        } else {
                            // This is the end of the `if .. else ..` cascade.
                            // We can stop here.
                            emit_suggestion(None);
                            empty_alt = true;
                            break;
                        }
                    }
                }
            }
            // At this point, any `if let` fragment in the cascade is definitely preceded by `else`,
            // so a opening bracket is mandatory before each `match`.
            add_bracket_to_match_head = true;
            if let Some(alt) = alt {
                expr = alt;
            } else {
                break;
            }
        }
        if let Some((span, hir_id)) = first_if_to_lint {
            tcx.emit_node_span_lint(
                IF_LET_RESCOPE,
                hir_id,
                span,
                IfLetRescopeLint {
                    destructors,
                    significant_droppers,
                    lifetime_ends,
                    rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite {
                        match_heads,
                        consequent_heads,
                        closing_brackets: ClosingBrackets {
                            span: expr_end,
                            count: closing_brackets,
                            empty_alt,
                        },
                        alt_heads,
                    }),
                },
            );
        }
    }
}

impl_lint_pass!(
    IfLetRescope => [IF_LET_RESCOPE]
);

impl<'tcx> LateLintPass<'tcx> for IfLetRescope {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
        if expr.span.edition().at_least_rust_2024()
            || cx.tcx.lints_that_dont_need_to_run(()).contains(&LintId::of(IF_LET_RESCOPE))
        {
            return;
        }

        if let hir::ExprKind::Loop(block, _label, hir::LoopSource::While, _span) = expr.kind
            && let Some(value) = block.expr
            && let hir::ExprKind::If(cond, _conseq, _alt) = value.kind
            && let hir::ExprKind::Let(..) = cond.kind
        {
            // Recall that `while let` is lowered into this:
            // ```
            // loop {
            //     if let .. { body } else { break; }
            // }
            // ```
            // There is no observable change in drop order on the overall `if let` expression
            // given that the `{ break; }` block is trivial so the edition change
            // means nothing substantial to this `while` statement.
            self.skip.insert(value.hir_id);
            return;
        }
        if expr_parent_is_stmt(cx.tcx, expr.hir_id)
            && matches!(expr.kind, hir::ExprKind::If(_cond, _conseq, None))
        {
            // `if let` statement without an `else` branch has no observable change
            // so we can skip linting it
            return;
        }
        self.probe_if_cascade(cx, expr);
    }
}

#[derive(LintDiagnostic)]
#[diag(lint_if_let_rescope)]
struct IfLetRescopeLint {
    #[subdiagnostic]
    destructors: Vec<DestructorLabel>,
    #[label]
    significant_droppers: Vec<Span>,
    #[help]
    lifetime_ends: Vec<Span>,
    #[subdiagnostic]
    rewrite: Option<IfLetRescopeRewrite>,
}

struct IfLetRescopeRewrite {
    match_heads: Vec<SingleArmMatchBegin>,
    consequent_heads: Vec<ConsequentRewrite>,
    closing_brackets: ClosingBrackets,
    alt_heads: Vec<AltHead>,
}

impl Subdiagnostic for IfLetRescopeRewrite {
    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
        let mut suggestions = vec![];
        for match_head in self.match_heads {
            match match_head {
                SingleArmMatchBegin::WithOpenBracket(span) => {
                    suggestions.push((span, "{ match ".into()))
                }
                SingleArmMatchBegin::WithoutOpenBracket(span) => {
                    suggestions.push((span, "match ".into()))
                }
            }
        }
        for ConsequentRewrite { span, pat } in self.consequent_heads {
            suggestions.push((span, format!("{{ {pat} => ")));
        }
        for AltHead(span) in self.alt_heads {
            suggestions.push((span, " _ => ".into()));
        }
        let closing_brackets = self.closing_brackets;
        suggestions.push((
            closing_brackets.span,
            closing_brackets
                .empty_alt
                .then_some(" _ => {}".chars())
                .into_iter()
                .flatten()
                .chain(repeat_n('}', closing_brackets.count))
                .collect(),
        ));
        let msg = diag.eagerly_translate(crate::fluent_generated::lint_suggestion);
        diag.multipart_suggestion_with_style(
            msg,
            suggestions,
            Applicability::MachineApplicable,
            SuggestionStyle::ShowCode,
        );
    }
}

#[derive(Subdiagnostic)]
#[note(lint_if_let_dtor)]
struct DestructorLabel {
    #[primary_span]
    span: Span,
    dtor_kind: &'static str,
}

struct AltHead(Span);

struct ConsequentRewrite {
    span: Span,
    pat: String,
}

struct ClosingBrackets {
    span: Span,
    count: usize,
    empty_alt: bool,
}
enum SingleArmMatchBegin {
    WithOpenBracket(Span),
    WithoutOpenBracket(Span),
}

struct FindSignificantDropper<'a, 'tcx> {
    cx: &'a LateContext<'tcx>,
}

impl<'tcx> FindSignificantDropper<'_, 'tcx> {
    /// Check the scrutinee of an `if let` to see if it promotes any temporary values
    /// that would change drop order in edition 2024. Specifically, it checks the value
    /// of the scrutinee itself, and also recurses into the expression to find any ref
    /// exprs (or autoref) which would promote temporaries that would be scoped to the
    /// end of this `if`.
    fn check_if_let_scrutinee(
        &mut self,
        init: &'tcx hir::Expr<'tcx>,
    ) -> ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)> {
        self.check_promoted_temp_with_drop(init)?;
        self.visit_expr(init)
    }

    /// Check that an expression is not a promoted temporary with a significant
    /// drop impl.
    ///
    /// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref)
    /// or is the scrutinee of the `if let`, *and* the expression is not a place
    /// expr, and it has a significant drop.
    fn check_promoted_temp_with_drop(
        &self,
        expr: &'tcx hir::Expr<'tcx>,
    ) -> ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)> {
        if expr.is_place_expr(|base| {
            self.cx
                .typeck_results()
                .adjustments()
                .get(base.hir_id)
                .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
        }) {
            return ControlFlow::Continue(());
        }

        let drop_tys = extract_component_with_significant_dtor(
            self.cx.tcx,
            self.cx.typing_env(),
            self.cx.typeck_results().expr_ty(expr),
        );
        if drop_tys.is_empty() {
            return ControlFlow::Continue(());
        }

        ControlFlow::Break((expr.span, drop_tys))
    }
}

impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
    type Result = ControlFlow<(Span, SmallVec<[Ty<'tcx>; 4]>)>;

    fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result {
        // Blocks introduce temporary terminating scope for all of its
        // statements, so just visit the tail expr, skipping over any
        // statements. This prevents false positives like `{ let x = &Drop; }`.
        if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) }
    }

    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
        // Check for promoted temporaries from autoref, e.g.
        // `if let None = TypeWithDrop.as_ref() {} else {}`
        // where `fn as_ref(&self) -> Option<...>`.
        for adj in self.cx.typeck_results().expr_adjustments(expr) {
            match adj.kind {
                // Skip when we hit the first deref expr.
                Adjust::Deref(_) => break,
                Adjust::Borrow(_) => {
                    self.check_promoted_temp_with_drop(expr)?;
                }
                _ => {}
            }
        }

        match expr.kind {
            // Account for cases like `if let None = Some(&Drop) {} else {}`.
            hir::ExprKind::AddrOf(_, _, expr) => {
                self.check_promoted_temp_with_drop(expr)?;
                intravisit::walk_expr(self, expr)
            }
            // `(Drop, ()).1` introduces a temporary and then moves out of
            // part of it, therefore we should check it for temporaries.
            // FIXME: This may have false positives if we move the part
            // that actually has drop, but oh well.
            hir::ExprKind::Index(expr, _, _) | hir::ExprKind::Field(expr, _) => {
                self.check_promoted_temp_with_drop(expr)?;
                intravisit::walk_expr(self, expr)
            }
            // If always introduces a temporary terminating scope for its cond and arms,
            // so don't visit them.
            hir::ExprKind::If(..) => ControlFlow::Continue(()),
            // Match introduces temporary terminating scopes for arms, so don't visit
            // them, and only visit the scrutinee to account for cases like:
            // `if let None = match &Drop { _ => Some(1) } {} else {}`.
            hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut),
            // Self explanatory.
            hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()),
            // Otherwise, walk into the expr's parts.
            _ => intravisit::walk_expr(self, expr),
        }
    }
}
