use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::{bug, ty};
use rustc_parse_format::{ParseMode, Parser, Piece};
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::{InnerSpan, Span, Symbol, hygiene, sym};
use rustc_trait_selection::infer::InferCtxtExt;

use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};

declare_lint! {
    /// The `non_fmt_panics` lint detects `panic!(..)` invocations where the first
    /// argument is not a formatting string.
    ///
    /// ### Example
    ///
    /// ```rust,no_run,edition2018
    /// panic!("{}");
    /// panic!(123);
    /// ```
    ///
    /// {{produces}}
    ///
    /// ### Explanation
    ///
    /// In Rust 2018 and earlier, `panic!(x)` directly uses `x` as the message.
    /// That means that `panic!("{}")` panics with the message `"{}"` instead
    /// of using it as a formatting string, and `panic!(123)` will panic with
    /// an `i32` as message.
    ///
    /// Rust 2021 always interprets the first argument as format string.
    NON_FMT_PANICS,
    Warn,
    "detect single-argument panic!() invocations in which the argument is not a format string",
    @future_incompatible = FutureIncompatibleInfo {
        reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021),
        explain_reason: false,
    };
    report_in_external_macro
}

declare_lint_pass!(NonPanicFmt => [NON_FMT_PANICS]);

impl<'tcx> LateLintPass<'tcx> for NonPanicFmt {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
        if let hir::ExprKind::Call(f, [arg]) = &expr.kind
            && let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind()
        {
            let f_diagnostic_name = cx.tcx.get_diagnostic_name(def_id);

            if cx.tcx.is_lang_item(def_id, LangItem::BeginPanic)
                || cx.tcx.is_lang_item(def_id, LangItem::Panic)
                || f_diagnostic_name == Some(sym::panic_str_2015)
            {
                if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
                    if matches!(
                        cx.tcx.get_diagnostic_name(id),
                        Some(sym::core_panic_2015_macro | sym::std_panic_2015_macro)
                    ) {
                        check_panic(cx, f, arg);
                    }
                }
            } else if f_diagnostic_name == Some(sym::unreachable_display) {
                if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id
                    && cx.tcx.is_diagnostic_item(sym::unreachable_2015_macro, id)
                {
                    check_panic(
                        cx,
                        f,
                        // This is safe because we checked above that the callee is indeed
                        // unreachable_display
                        match &arg.kind {
                            // Get the borrowed arg not the borrow
                            hir::ExprKind::AddrOf(ast::BorrowKind::Ref, _, arg) => arg,
                            _ => bug!("call to unreachable_display without borrow"),
                        },
                    );
                }
            }
        }
    }
}

fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) {
    if let hir::ExprKind::Lit(lit) = &arg.kind {
        if let ast::LitKind::Str(sym, _) = lit.node {
            // The argument is a string literal.
            check_panic_str(cx, f, arg, sym.as_str());
            return;
        }
    }

    // The argument is *not* a string literal.

    let (span, panic, symbol) = panic_call(cx, f);

    if span.in_external_macro(cx.sess().source_map()) {
        // Nothing that can be done about it in the current crate.
        return;
    }

    // Find the span of the argument to `panic!()` or `unreachable!`, before expansion in the
    // case of `panic!(some_macro!())` or `unreachable!(some_macro!())`.
    // We don't use source_callsite(), because this `panic!(..)` might itself
    // be expanded from another macro, in which case we want to stop at that
    // expansion.
    let mut arg_span = arg.span;
    let mut arg_macro = None;
    while !span.contains(arg_span) {
        let ctxt = arg_span.ctxt();
        if ctxt.is_root() {
            break;
        }
        let expn = ctxt.outer_expn_data();
        arg_macro = expn.macro_def_id;
        arg_span = expn.call_site;
    }

    #[allow(rustc::diagnostic_outside_of_impl)]
    cx.span_lint(NON_FMT_PANICS, arg_span, |lint| {
        lint.primary_message(fluent::lint_non_fmt_panic);
        lint.arg("name", symbol);
        lint.note(fluent::lint_note);
        lint.note(fluent::lint_more_info_note);
        if !is_arg_inside_call(arg_span, span) {
            // No clue where this argument is coming from.
            return;
        }
        if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
            // A case of `panic!(format!(..))`.
            lint.note(fluent::lint_supports_fmt_note);
            if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
                lint.multipart_suggestion(
                    fluent::lint_supports_fmt_suggestion,
                    vec![
                        (arg_span.until(open.shrink_to_hi()), "".into()),
                        (close.until(arg_span.shrink_to_hi()), "".into()),
                    ],
                    Applicability::MachineApplicable,
                );
            }
        } else {
            let ty = cx.typeck_results().expr_ty(arg);
            // If this is a &str or String, we can confidently give the `"{}", ` suggestion.
            let is_str = matches!(
                ty.kind(),
                ty::Ref(_, r, _) if r.is_str(),
            ) || matches!(
                ty.ty_adt_def(),
                Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String),
            );

            let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env());
            let suggest_display = is_str
                || cx
                    .tcx
                    .get_diagnostic_item(sym::Display)
                    .is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());
            let suggest_debug = !suggest_display
                && cx
                    .tcx
                    .get_diagnostic_item(sym::Debug)
                    .is_some_and(|t| infcx.type_implements_trait(t, [ty], param_env).may_apply());

            let suggest_panic_any = !is_str && panic == Some(sym::std_panic_macro);

            let fmt_applicability = if suggest_panic_any {
                // If we can use panic_any, use that as the MachineApplicable suggestion.
                Applicability::MaybeIncorrect
            } else {
                // If we don't suggest panic_any, using a format string is our best bet.
                Applicability::MachineApplicable
            };

            if suggest_display {
                lint.span_suggestion_verbose(
                    arg_span.shrink_to_lo(),
                    fluent::lint_display_suggestion,
                    "\"{}\", ",
                    fmt_applicability,
                );
            } else if suggest_debug {
                lint.arg("ty", ty);
                lint.span_suggestion_verbose(
                    arg_span.shrink_to_lo(),
                    fluent::lint_debug_suggestion,
                    "\"{:?}\", ",
                    fmt_applicability,
                );
            }

            if suggest_panic_any {
                if let Some((open, close, del)) = find_delimiters(cx, span) {
                    lint.arg("already_suggested", suggest_display || suggest_debug);
                    lint.multipart_suggestion(
                        fluent::lint_panic_suggestion,
                        if del == '(' {
                            vec![(span.until(open), "std::panic::panic_any".into())]
                        } else {
                            vec![
                                (span.until(open.shrink_to_hi()), "std::panic::panic_any(".into()),
                                (close, ")".into()),
                            ]
                        },
                        Applicability::MachineApplicable,
                    );
                }
            }
        }
    });
}

fn check_panic_str<'tcx>(
    cx: &LateContext<'tcx>,
    f: &'tcx hir::Expr<'tcx>,
    arg: &'tcx hir::Expr<'tcx>,
    fmt: &str,
) {
    if !fmt.contains(&['{', '}']) {
        // No brace, no problem.
        return;
    }

    let (span, _, _) = panic_call(cx, f);

    let sm = cx.sess().source_map();
    if span.in_external_macro(sm) && arg.span.in_external_macro(sm) {
        // Nothing that can be done about it in the current crate.
        return;
    }

    let fmt_span = arg.span.source_callsite();

    let (snippet, style) = match sm.span_to_snippet(fmt_span) {
        Ok(snippet) => {
            // Count the number of `#`s between the `r` and `"`.
            let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
            (Some(snippet), style)
        }
        Err(_) => (None, None),
    };

    let mut fmt_parser = Parser::new(fmt, style, snippet.clone(), false, ParseMode::Format);
    let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();

    if n_arguments > 0 && fmt_parser.errors.is_empty() {
        let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] {
            [] => vec![fmt_span],
            v => v
                .iter()
                .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
                .collect(),
        };
        cx.emit_span_lint(
            NON_FMT_PANICS,
            arg_spans,
            NonFmtPanicUnused {
                count: n_arguments,
                suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span),
            },
        );
    } else {
        let brace_spans: Option<Vec<_>> =
            snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| {
                s.char_indices()
                    .filter(|&(_, c)| c == '{' || c == '}')
                    .map(|(i, _)| fmt_span.from_inner(InnerSpan { start: i, end: i + 1 }))
                    .collect()
            });
        let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2);
        cx.emit_span_lint(
            NON_FMT_PANICS,
            brace_spans.unwrap_or_else(|| vec![span]),
            NonFmtPanicBraces {
                count,
                suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span.shrink_to_lo()),
            },
        );
    }
}

/// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
/// and the type of (opening) delimiter used.
fn find_delimiters(cx: &LateContext<'_>, span: Span) -> Option<(Span, Span, char)> {
    let snippet = cx.sess().source_map().span_to_snippet(span).ok()?;
    let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
    let close = snippet.rfind(|c| ")]}".contains(c))?;
    Some((
        span.from_inner(InnerSpan { start: open, end: open + 1 }),
        span.from_inner(InnerSpan { start: close, end: close + 1 }),
        open_ch,
    ))
}

fn panic_call<'tcx>(
    cx: &LateContext<'tcx>,
    f: &'tcx hir::Expr<'tcx>,
) -> (Span, Option<Symbol>, Symbol) {
    let mut expn = f.span.ctxt().outer_expn_data();

    let mut panic_macro = None;

    // Unwrap more levels of macro expansion, as panic_2015!()
    // was likely expanded from panic!() and possibly from
    // [debug_]assert!().
    loop {
        let parent = expn.call_site.ctxt().outer_expn_data();
        let Some(id) = parent.macro_def_id else { break };
        let Some(name) = cx.tcx.get_diagnostic_name(id) else { break };
        if !matches!(
            name,
            sym::core_panic_macro
                | sym::std_panic_macro
                | sym::assert_macro
                | sym::debug_assert_macro
                | sym::unreachable_macro
        ) {
            break;
        }
        expn = parent;
        panic_macro = Some(name);
    }

    let macro_symbol =
        if let hygiene::ExpnKind::Macro(_, symbol) = expn.kind { symbol } else { sym::panic };
    (expn.call_site, panic_macro, macro_symbol)
}

fn is_arg_inside_call(arg: Span, call: Span) -> bool {
    // We only add suggestions if the argument we're looking at appears inside the
    // panic call in the source file, to avoid invalid suggestions when macros are involved.
    // We specifically check for the spans to not be identical, as that happens sometimes when
    // proc_macros lie about spans and apply the same span to all the tokens they produce.
    call.contains(arg) && !call.source_equal(arg)
}
