use rustc_data_structures::fx::FxHashSet;
use rustc_hir::CRATE_OWNER_ID;
use rustc_middle::lint::LintExpectation;
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::LintExpectationId;
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
use rustc_span::Symbol;

use crate::lints::{Expectation, ExpectationNote};

pub(crate) fn provide(providers: &mut Providers) {
    *providers = Providers { lint_expectations, check_expectations, ..*providers };
}

fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
    let krate = tcx.hir_crate_items(());

    let mut expectations = Vec::new();

    for owner in std::iter::once(CRATE_OWNER_ID).chain(krate.owners()) {
        let lints = tcx.shallow_lint_levels_on(owner);
        expectations.extend_from_slice(&lints.expectations);
    }

    expectations
}

fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
    let lint_expectations = tcx.lint_expectations(());
    let fulfilled_expectations = tcx.dcx().steal_fulfilled_expectation_ids();

    // Turn a `LintExpectationId` into a `(AttrId, lint_index)` pair.
    let canonicalize_id = |expect_id: &LintExpectationId| {
        match *expect_id {
            LintExpectationId::Unstable { attr_id, lint_index: Some(lint_index) } => {
                (attr_id, lint_index)
            }
            LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
                // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok.
                let attr_id = tcx.hir().attrs(hir_id)[attr_index as usize].id;
                (attr_id, lint_index)
            }
            _ => panic!("fulfilled expectations must have a lint index"),
        }
    };

    let fulfilled_expectations: FxHashSet<_> =
        fulfilled_expectations.iter().map(canonicalize_id).collect();

    for (expect_id, expectation) in lint_expectations {
        // This check will always be true, since `lint_expectations` only holds stable ids
        let LintExpectationId::Stable { hir_id, .. } = expect_id else {
            unreachable!("at this stage all `LintExpectationId`s are stable");
        };

        let expect_id = canonicalize_id(expect_id);

        if !fulfilled_expectations.contains(&expect_id)
            && tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
        {
            let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale });
            let note = expectation.is_unfulfilled_lint_expectations;
            tcx.emit_node_span_lint(
                UNFULFILLED_LINT_EXPECTATIONS,
                *hir_id,
                expectation.emission_span,
                Expectation { rationale, note },
            );
        }
    }
}
