use std::iter::repeat;
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('}').take(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),
        }
    }
}
