#![allow(clippy::print_stderr)]

mod overly_long_real_world_cases;

use hir::setup_tracing;
use ide_db::{
    LineIndexDatabase, RootDatabase,
    assists::{AssistResolveStrategy, ExprFillDefaultMode},
    base_db::SourceDatabase,
};
use itertools::Itertools;
use stdx::trim_indent;
use test_fixture::WithFixture;
use test_utils::{MiniCore, assert_eq_text, extract_annotations};

use crate::{DiagnosticsConfig, Severity};

/// Takes a multi-file input fixture with annotated cursor positions,
/// and checks that:
///  * a diagnostic is produced
///  * the first diagnostic fix trigger range touches the input cursor position
///  * that the contents of the file containing the cursor match `after` after the diagnostic fix is applied
#[track_caller]
pub(crate) fn check_fix(
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
) {
    check_nth_fix(0, ra_fixture_before, ra_fixture_after);
}
/// Takes a multi-file input fixture with annotated cursor positions,
/// and checks that:
///  * a diagnostic is produced
///  * every diagnostic fixes trigger range touches the input cursor position
///  * that the contents of the file containing the cursor match `after` after each diagnostic fix is applied
pub(crate) fn check_fixes(
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    ra_fixtures_after: Vec<&str>,
) {
    for (i, ra_fixture_after) in ra_fixtures_after.iter().enumerate() {
        check_nth_fix(i, ra_fixture_before, ra_fixture_after)
    }
}

#[track_caller]
fn check_nth_fix(
    nth: usize,
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
) {
    let mut config = DiagnosticsConfig::test_sample();
    config.expr_fill_default = ExprFillDefaultMode::Default;
    check_nth_fix_with_config(config, nth, ra_fixture_before, ra_fixture_after)
}

#[track_caller]
pub(crate) fn check_fix_with_disabled(
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
    disabled: impl Iterator<Item = String>,
) {
    let mut config = DiagnosticsConfig::test_sample();
    config.expr_fill_default = ExprFillDefaultMode::Default;
    config.disabled.extend(disabled);
    check_nth_fix_with_config(config, 0, ra_fixture_before, ra_fixture_after)
}

#[track_caller]
fn check_nth_fix_with_config(
    config: DiagnosticsConfig,
    nth: usize,
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
) {
    let after = trim_indent(ra_fixture_after);

    let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
    let diagnostic = hir::attach_db(&db, || {
        super::full_diagnostics(
            &db,
            &config,
            &AssistResolveStrategy::All,
            file_position.file_id.file_id(&db),
        )
        .pop()
        .expect("no diagnostics")
    });
    let fix = &diagnostic
        .fixes
        .unwrap_or_else(|| panic!("{:?} diagnostic misses fixes", diagnostic.code))[nth];
    let actual = {
        let source_change = fix.source_change.as_ref().unwrap();
        let file_id = *source_change.source_file_edits.keys().next().unwrap();
        let mut actual = db.file_text(file_id).text(&db).to_string();

        for (edit, snippet_edit) in source_change.source_file_edits.values() {
            edit.apply(&mut actual);
            if let Some(snippet_edit) = snippet_edit {
                snippet_edit.apply(&mut actual);
            }
        }
        actual
    };

    assert!(
        fix.target.contains_inclusive(file_position.offset),
        "diagnostic fix range {:?} does not touch cursor position {:?}",
        fix.target,
        file_position.offset
    );
    assert_eq_text!(&after, &actual);
}

pub(crate) fn check_fixes_unordered(
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    ra_fixtures_after: Vec<&str>,
) {
    for ra_fixture_after in ra_fixtures_after.iter() {
        check_has_fix(ra_fixture_before, ra_fixture_after)
    }
}

#[track_caller]
pub(crate) fn check_has_fix(
    #[rust_analyzer::rust_fixture] ra_fixture_before: &str,
    #[rust_analyzer::rust_fixture] ra_fixture_after: &str,
) {
    let after = trim_indent(ra_fixture_after);

    let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
    let mut conf = DiagnosticsConfig::test_sample();
    conf.expr_fill_default = ExprFillDefaultMode::Default;
    let fix = hir::attach_db(&db, || {
        super::full_diagnostics(
            &db,
            &conf,
            &AssistResolveStrategy::All,
            file_position.file_id.file_id(&db),
        )
    })
    .into_iter()
    .find(|d| {
        d.fixes
            .as_ref()
            .and_then(|fixes| {
                fixes.iter().find(|fix| {
                    if !fix.target.contains_inclusive(file_position.offset) {
                        return false;
                    }
                    let actual = {
                        let source_change = fix.source_change.as_ref().unwrap();
                        let file_id = *source_change.source_file_edits.keys().next().unwrap();
                        let mut actual = db.file_text(file_id).text(&db).to_string();

                        for (edit, snippet_edit) in source_change.source_file_edits.values() {
                            edit.apply(&mut actual);
                            if let Some(snippet_edit) = snippet_edit {
                                snippet_edit.apply(&mut actual);
                            }
                        }
                        actual
                    };
                    after == actual
                })
            })
            .is_some()
    });
    assert!(fix.is_some(), "no diagnostic with desired fix");
}

/// Checks that there's a diagnostic *without* fix at `$0`.
pub(crate) fn check_no_fix(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
    let (db, file_position) = RootDatabase::with_position(ra_fixture);
    let diagnostic = hir::attach_db(&db, || {
        super::full_diagnostics(
            &db,
            &DiagnosticsConfig::test_sample(),
            &AssistResolveStrategy::All,
            file_position.file_id.file_id(&db),
        )
    })
    .pop()
    .unwrap();
    assert!(diagnostic.fixes.is_none(), "got a fix when none was expected: {diagnostic:?}");
}

#[track_caller]
pub(crate) fn check_diagnostics(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
    let mut config = DiagnosticsConfig::test_sample();
    config.disabled.insert("inactive-code".to_owned());
    check_diagnostics_with_config(config, ra_fixture)
}

#[track_caller]
pub(crate) fn check_diagnostics_with_disabled(
    #[rust_analyzer::rust_fixture] ra_fixture: &str,
    disabled: &[&str],
) {
    let mut config = DiagnosticsConfig::test_sample();
    config.disabled.extend(disabled.iter().map(|&s| s.to_owned()));
    check_diagnostics_with_config(config, ra_fixture)
}

#[track_caller]
pub(crate) fn check_diagnostics_with_config(
    config: DiagnosticsConfig,
    #[rust_analyzer::rust_fixture] ra_fixture: &str,
) {
    let _tracing = setup_tracing();

    let (db, files) = RootDatabase::with_many_files(ra_fixture);
    let mut annotations = files
        .iter()
        .copied()
        .flat_map(|file_id| {
            hir::attach_db(&db, || {
                super::full_diagnostics(
                    &db,
                    &config,
                    &AssistResolveStrategy::All,
                    file_id.file_id(&db),
                )
                .into_iter()
                .map(|d| {
                    let mut annotation = String::new();
                    if let Some(fixes) = &d.fixes {
                        assert!(!fixes.is_empty());
                        annotation.push_str("💡 ")
                    }
                    annotation.push_str(match d.severity {
                        Severity::Error => "error",
                        Severity::WeakWarning => "weak",
                        Severity::Warning => "warn",
                        Severity::Allow => "allow",
                    });
                    annotation.push_str(": ");
                    annotation.push_str(&d.message);
                    (d.range, annotation)
                })
            })
        })
        .map(|(diagnostic, annotation)| (diagnostic.file_id, (diagnostic.range, annotation)))
        .into_group_map();
    for file_id in files {
        let file_id = file_id.file_id(&db);
        let line_index = db.line_index(file_id);

        let mut actual = annotations.remove(&file_id).unwrap_or_default();
        let mut expected = extract_annotations(db.file_text(file_id).text(&db));
        expected.sort_by_key(|(range, s)| (range.start(), s.clone()));
        actual.sort_by_key(|(range, s)| (range.start(), s.clone()));
        // FIXME: We should panic on duplicates instead, but includes currently cause us to report
        // diagnostics twice for the calling module when both files are queried.
        actual.dedup();
        // actual.iter().duplicates().for_each(|(range, msg)| {
        //     panic!("duplicate diagnostic at {:?}: {msg:?}", line_index.line_col(range.start()))
        // });
        if expected.is_empty() {
            // makes minicore smoke test debuggable
            for (e, _) in &actual {
                eprintln!(
                    "Code in range {e:?} = {}",
                    &db.file_text(file_id).text(&db)[usize::from(e.start())..usize::from(e.end())]
                )
            }
        }
        if expected != actual {
            let fneg = expected
                .iter()
                .filter(|x| !actual.contains(x))
                .map(|(range, s)| (line_index.line_col(range.start()), range, s))
                .collect::<Vec<_>>();
            let fpos = actual
                .iter()
                .filter(|x| !expected.contains(x))
                .map(|(range, s)| (line_index.line_col(range.start()), range, s))
                .collect::<Vec<_>>();

            panic!("Diagnostic test failed.\nFalse negatives: {fneg:?}\nFalse positives: {fpos:?}");
        }
    }
}

#[test]
fn test_disabled_diagnostics() {
    let mut config = DiagnosticsConfig::test_sample();
    config.disabled.insert("E0583".into());

    let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#);
    let file_id = file_id.file_id(&db);

    let diagnostics = hir::attach_db(&db, || {
        super::full_diagnostics(&db, &config, &AssistResolveStrategy::All, file_id)
    });
    assert!(diagnostics.is_empty());

    let diagnostics = hir::attach_db(&db, || {
        super::full_diagnostics(
            &db,
            &DiagnosticsConfig::test_sample(),
            &AssistResolveStrategy::All,
            file_id,
        )
    });
    assert!(!diagnostics.is_empty());
}

#[test]
fn minicore_smoke_test() {
    if test_utils::skip_slow_tests() {
        return;
    }

    fn check(minicore: MiniCore) {
        let source = minicore.source_code(MiniCore::RAW_SOURCE);
        let mut config = DiagnosticsConfig::test_sample();
        // This should be ignored since we conditionally remove code which creates single item use with braces
        config.disabled.insert("unused_braces".to_owned());
        config.disabled.insert("unused_variables".to_owned());
        config.disabled.insert("remove-unnecessary-else".to_owned());
        check_diagnostics_with_config(config, &source);
    }

    // Checks that there is no diagnostic in minicore for each flag.
    for flag in MiniCore::available_flags(MiniCore::RAW_SOURCE) {
        if flag == "clone" {
            // Clone without copy has `moved-out-of-ref`, so ignoring.
            // FIXME: Maybe we should merge copy and clone in a single flag?
            continue;
        }
        eprintln!("Checking minicore flag {flag}");
        check(MiniCore::from_flags([flag]));
    }
    // And one time for all flags, to check codes which are behind multiple flags + prevent name collisions
    eprintln!("Checking all minicore flags");
    check(MiniCore::from_flags(MiniCore::available_flags(MiniCore::RAW_SOURCE)))
}
