#![allow(clippy::print_stderr)]

mod overly_long_real_world_cases;

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 = 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 = 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 = 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 (db, files) = RootDatabase::with_many_files(ra_fixture);
    let mut annotations = files
        .iter()
        .copied()
        .flat_map(|file_id| {
            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 = super::full_diagnostics(&db, &config, &AssistResolveStrategy::All, file_id);
    assert!(diagnostics.is_empty());

    let diagnostics = 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();
        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() {
        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()))
}
