use std::borrow::Cow;

use rustc_ast::token::{self, Token};
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
use rustc_macros::Subdiagnostic;
use rustc_parse::parser::{Parser, Recovery, token_descr};
use rustc_session::parse::ParseSess;
use rustc_span::source_map::SourceMap;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span};
use tracing::debug;

use super::macro_rules::{MacroRule, NoopTracker, parser_from_cx};
use crate::expand::{AstFragmentKind, parse_ast_fragment};
use crate::mbe::macro_parser::ParseResult::*;
use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser};
use crate::mbe::macro_rules::{
    Tracker, try_match_macro, try_match_macro_attr, try_match_macro_derive,
};

pub(super) enum FailedMacro<'a> {
    Func,
    Attr(&'a TokenStream),
    Derive,
}

pub(super) fn failed_to_match_macro(
    psess: &ParseSess,
    sp: Span,
    def_span: Span,
    name: Ident,
    args: FailedMacro<'_>,
    body: &TokenStream,
    rules: &[MacroRule],
) -> (Span, ErrorGuaranteed) {
    debug!("failed to match macro");
    let def_head_span = if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
        psess.source_map().guess_head_span(def_span)
    } else {
        DUMMY_SP
    };

    // An error occurred, try the expansion again, tracking the expansion closely for better
    // diagnostics.
    let mut tracker = CollectTrackerAndEmitter::new(psess.dcx(), sp);

    let try_success_result = match args {
        FailedMacro::Func => try_match_macro(psess, name, body, rules, &mut tracker),
        FailedMacro::Attr(attr_args) => {
            try_match_macro_attr(psess, name, attr_args, body, rules, &mut tracker)
        }
        FailedMacro::Derive => try_match_macro_derive(psess, name, body, rules, &mut tracker),
    };

    if try_success_result.is_ok() {
        // Nonterminal parser recovery might turn failed matches into successful ones,
        // but for that it must have emitted an error already
        assert!(
            tracker.dcx.has_errors().is_some(),
            "Macro matching returned a success on the second try"
        );
    }

    if let Some(result) = tracker.result {
        // An irrecoverable error occurred and has been emitted.
        return result;
    }

    let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
    else {
        return (sp, psess.dcx().span_delayed_bug(sp, "failed to match a macro"));
    };

    let span = token.span.substitute_dummy(sp);

    let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None));
    err.span_label(span, label);
    if !def_head_span.is_dummy() {
        err.span_label(def_head_span, "when calling this macro");
    }

    annotate_doc_comment(&mut err, psess.source_map(), span);

    if let Some(span) = remaining_matcher.span() {
        err.span_note(span, format!("while trying to match {remaining_matcher}"));
    } else {
        err.note(format!("while trying to match {remaining_matcher}"));
    }

    if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
        && (matches!(expected_token.kind, token::OpenInvisible(_))
            || matches!(token.kind, token::OpenInvisible(_)))
    {
        err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
        err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");

        if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) {
            err.help("try using `:tt` instead in the macro definition");
        }
    }

    // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
    if let FailedMacro::Func = args
        && let Some((body, comma_span)) = body.add_comma()
    {
        for rule in rules {
            let MacroRule::Func { lhs, .. } = rule else { continue };
            let parser = parser_from_cx(psess, body.clone(), Recovery::Allowed);
            let mut tt_parser = TtParser::new(name);

            if let Success(_) =
                tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker)
            {
                if comma_span.is_dummy() {
                    err.note("you might be missing a comma");
                } else {
                    err.span_suggestion_short(
                        comma_span,
                        "missing comma here",
                        ", ",
                        Applicability::MachineApplicable,
                    );
                }
            }
        }
    }
    let guar = err.emit();
    (sp, guar)
}

/// The tracker used for the slow error path that collects useful info for diagnostics.
struct CollectTrackerAndEmitter<'dcx, 'matcher> {
    dcx: DiagCtxtHandle<'dcx>,
    remaining_matcher: Option<&'matcher MatcherLoc>,
    /// Which arm's failure should we report? (the one furthest along)
    best_failure: Option<BestFailure>,
    root_span: Span,
    result: Option<(Span, ErrorGuaranteed)>,
}

struct BestFailure {
    token: Token,
    position_in_tokenstream: (bool, u32),
    msg: &'static str,
    remaining_matcher: MatcherLoc,
}

impl BestFailure {
    fn is_better_position(&self, position: (bool, u32)) -> bool {
        position > self.position_in_tokenstream
    }
}

impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'matcher> {
    type Failure = (Token, u32, &'static str);

    fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure {
        (tok, position, msg)
    }

    fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) {
        if self.remaining_matcher.is_none()
            || (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof)
        {
            self.remaining_matcher = Some(matcher);
        }
    }

    fn after_arm(&mut self, in_body: bool, result: &NamedParseResult<Self::Failure>) {
        match result {
            Success(_) => {
                // Nonterminal parser recovery might turn failed matches into successful ones,
                // but for that it must have emitted an error already
                self.dcx.span_delayed_bug(
                    self.root_span,
                    "should not collect detailed info for successful macro match",
                );
            }
            Failure((token, approx_position, msg)) => {
                debug!(?token, ?msg, "a new failure of an arm");

                let position_in_tokenstream = (in_body, *approx_position);
                if self
                    .best_failure
                    .as_ref()
                    .is_none_or(|failure| failure.is_better_position(position_in_tokenstream))
                {
                    self.best_failure = Some(BestFailure {
                        token: *token,
                        position_in_tokenstream,
                        msg,
                        remaining_matcher: self
                            .remaining_matcher
                            .expect("must have collected matcher already")
                            .clone(),
                    })
                }
            }
            Error(err_sp, msg) => {
                let span = err_sp.substitute_dummy(self.root_span);
                let guar = self.dcx.span_err(span, msg.clone());
                self.result = Some((span, guar));
            }
            ErrorReported(guar) => self.result = Some((self.root_span, *guar)),
        }
    }

    fn description() -> &'static str {
        "detailed"
    }

    fn recovery() -> Recovery {
        Recovery::Allowed
    }
}

impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {
    fn new(dcx: DiagCtxtHandle<'dcx>, root_span: Span) -> Self {
        Self { dcx, remaining_matcher: None, best_failure: None, root_span, result: None }
    }
}

pub(super) fn emit_frag_parse_err(
    mut e: Diag<'_>,
    parser: &Parser<'_>,
    orig_parser: &mut Parser<'_>,
    site_span: Span,
    arm_span: Span,
    kind: AstFragmentKind,
) -> ErrorGuaranteed {
    // FIXME(davidtwco): avoid depending on the error message text
    if parser.token == token::Eof
        && let DiagMessage::Str(message) = &e.messages[0].0
        && message.ends_with(", found `<eof>`")
    {
        let msg = &e.messages[0];
        e.messages[0] = (
            DiagMessage::from(format!(
                "macro expansion ends with an incomplete expression: {}",
                message.replace(", found `<eof>`", ""),
            )),
            msg.1,
        );
        if !e.span.is_dummy() {
            // early end of macro arm (#52866)
            e.replace_span_with(parser.token.span.shrink_to_hi(), true);
        }
    }
    if e.span.is_dummy() {
        // Get around lack of span in error (#30128)
        e.replace_span_with(site_span, true);
        if !parser.psess.source_map().is_imported(arm_span) {
            e.span_label(arm_span, "in this macro arm");
        }
    } else if parser.psess.source_map().is_imported(parser.token.span) {
        e.span_label(site_span, "in this macro invocation");
    }
    match kind {
        // Try a statement if an expression is wanted but failed and suggest adding `;` to call.
        AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
            Err(err) => err.cancel(),
            Ok(_) => {
                e.note(
                    "the macro call doesn't expand to an expression, but it can expand to a statement",
                );

                if parser.token == token::Semi {
                    if let Ok(snippet) = parser.psess.source_map().span_to_snippet(site_span) {
                        e.span_suggestion_verbose(
                            site_span,
                            "surround the macro invocation with `{}` to interpret the expansion as a statement",
                            format!("{{ {snippet}; }}"),
                            Applicability::MaybeIncorrect,
                        );
                    }
                } else {
                    e.span_suggestion_verbose(
                        site_span.shrink_to_hi(),
                        "add `;` to interpret the expansion as a statement",
                        ";",
                        Applicability::MaybeIncorrect,
                    );
                }
            }
        },
        _ => annotate_err_with_kind(&mut e, kind, site_span),
    };
    e.emit()
}

pub(crate) fn annotate_err_with_kind(err: &mut Diag<'_>, kind: AstFragmentKind, span: Span) {
    match kind {
        AstFragmentKind::Ty => {
            err.span_label(span, "this macro call doesn't expand to a type");
        }
        AstFragmentKind::Pat => {
            err.span_label(span, "this macro call doesn't expand to a pattern");
        }
        _ => {}
    };
}

#[derive(Subdiagnostic)]
enum ExplainDocComment {
    #[label(expand_explain_doc_comment_inner)]
    Inner {
        #[primary_span]
        span: Span,
    },
    #[label(expand_explain_doc_comment_outer)]
    Outer {
        #[primary_span]
        span: Span,
    },
}

fn annotate_doc_comment(err: &mut Diag<'_>, sm: &SourceMap, span: Span) {
    if let Ok(src) = sm.span_to_snippet(span) {
        if src.starts_with("///") || src.starts_with("/**") {
            err.subdiagnostic(ExplainDocComment::Outer { span });
        } else if src.starts_with("//!") || src.starts_with("/*!") {
            err.subdiagnostic(ExplainDocComment::Inner { span });
        }
    }
}

/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For
/// other tokens, this is "unexpected token...".
fn parse_failure_msg(tok: &Token, expected_token: Option<&Token>) -> Cow<'static, str> {
    if let Some(expected_token) = expected_token {
        Cow::from(format!("expected {}, found {}", token_descr(expected_token), token_descr(tok)))
    } else {
        match tok.kind {
            token::Eof => Cow::from("unexpected end of macro invocation"),
            _ => Cow::from(format!("no rules expected {}", token_descr(tok))),
        }
    }
}
