use rustc_lint_defs::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_span::ErrorGuaranteed;
use tracing::instrument;

use crate::MatchArm;
use crate::constructor::Constructor;
use crate::diagnostics::{
    NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered,
};
use crate::pat_column::PatternColumn;
use crate::rustc::{RevealedTy, RustcPatCtxt, WitnessPat};

/// Traverse the patterns to collect any variants of a non_exhaustive enum that fail to be mentioned
/// in a given column.
#[instrument(level = "debug", skip(cx), ret)]
fn collect_nonexhaustive_missing_variants<'p, 'tcx>(
    cx: &RustcPatCtxt<'p, 'tcx>,
    column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>,
) -> Result<Vec<WitnessPat<'p, 'tcx>>, ErrorGuaranteed> {
    let Some(&ty) = column.head_ty() else {
        return Ok(Vec::new());
    };

    let set = column.analyze_ctors(cx, &ty)?;
    if set.present.is_empty() {
        // We can't consistently handle the case where no constructors are present (since this would
        // require digging deep through any type in case there's a non_exhaustive enum somewhere),
        // so for consistency we refuse to handle the top-level case, where we could handle it.
        return Ok(Vec::new());
    }

    let mut witnesses = Vec::new();
    if cx.is_foreign_non_exhaustive_enum(ty) {
        witnesses.extend(
            set.missing
                .into_iter()
                // This will list missing visible variants.
                .filter(|c| !matches!(c, Constructor::Hidden | Constructor::NonExhaustive))
                .map(|missing_ctor| WitnessPat::wild_from_ctor(cx, missing_ctor, ty)),
        )
    }

    // Recurse into the fields.
    for ctor in set.present {
        let specialized_columns = column.specialize(cx, &ty, &ctor);
        let wild_pat = WitnessPat::wild_from_ctor(cx, ctor, ty);
        for (i, col_i) in specialized_columns.iter().enumerate() {
            // Compute witnesses for each column.
            let wits_for_col_i = collect_nonexhaustive_missing_variants(cx, col_i)?;
            // For each witness, we build a new pattern in the shape of `ctor(_, _, wit, _, _)`,
            // adding enough wildcards to match `arity`.
            for wit in wits_for_col_i {
                let mut pat = wild_pat.clone();
                pat.fields[i] = wit;
                witnesses.push(pat);
            }
        }
    }
    Ok(witnesses)
}

pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
    rcx: &RustcPatCtxt<'p, 'tcx>,
    arms: &[MatchArm<'p, RustcPatCtxt<'p, 'tcx>>],
    pat_column: &PatternColumn<'p, RustcPatCtxt<'p, 'tcx>>,
    scrut_ty: RevealedTy<'tcx>,
) -> Result<(), ErrorGuaranteed> {
    if !rcx
        .tcx
        .lint_level_spec_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, rcx.match_lint_level)
        .is_allow()
    {
        let witnesses = collect_nonexhaustive_missing_variants(rcx, pat_column)?;
        if !witnesses.is_empty() {
            // Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
            // is not exhaustive enough.
            //
            // NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`.
            rcx.tcx.emit_node_span_lint(
                NON_EXHAUSTIVE_OMITTED_PATTERNS,
                rcx.match_lint_level,
                rcx.scrut_span,
                NonExhaustiveOmittedPattern {
                    scrut_ty: scrut_ty.inner(),
                    uncovered: Uncovered::new(rcx.scrut_span, rcx, witnesses),
                },
            );
        }
    } else {
        // We used to allow putting the `#[allow(non_exhaustive_omitted_patterns)]` on a match
        // arm. This no longer makes sense so we warn users, to avoid silently breaking their
        // usage of the lint.
        for arm in arms {
            let level_spec =
                rcx.tcx.lint_level_spec_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.arm_data);
            let level = level_spec.level();
            if level != rustc_lint_defs::Level::Allow {
                rcx.tcx.dcx().emit_warn(NonExhaustiveOmittedPatternLintOnArm {
                    span: arm.pat.data().span,
                    lint_span: level_spec.src.span(),
                    suggest_lint_on_match: rcx.whole_match_span.map(|span| span.shrink_to_lo()),
                    lint_level: level.as_str(),
                    lint_name: "non_exhaustive_omitted_patterns",
                });
            }
        }
    }
    Ok(())
}
