//! This module provides an SSR assist. It is not desirable to include this
//! assist in ide_assists because that would require the ide_assists crate
//! depend on the ide_ssr crate.

use ide_assists::{Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel};
use ide_db::{FileRange, RootDatabase, label::Label, source_change::SourceChange};

pub(crate) fn ssr_assists(
    db: &RootDatabase,
    resolve: &AssistResolveStrategy,
    frange: FileRange,
) -> Vec<Assist> {
    let mut ssr_assists = Vec::with_capacity(2);

    let (match_finder, comment_range) = match ide_ssr::ssr_from_comment(db, frange) {
        Some(ssr_data) => ssr_data,
        None => return ssr_assists,
    };
    let id = AssistId("ssr", AssistKind::RefactorRewrite);

    let (source_change_for_file, source_change_for_workspace) = if resolve.should_resolve(&id) {
        let edits = match_finder.edits();

        let source_change_for_file = {
            let text_edit_for_file = edits.get(&frange.file_id).cloned().unwrap_or_default();
            SourceChange::from_text_edit(frange.file_id, text_edit_for_file)
        };

        let source_change_for_workspace = SourceChange::from_iter(match_finder.edits());

        (Some(source_change_for_file), Some(source_change_for_workspace))
    } else {
        (None, None)
    };

    let assists = vec![
        ("Apply SSR in file", source_change_for_file),
        ("Apply SSR in workspace", source_change_for_workspace),
    ];

    for (label, source_change) in assists.into_iter() {
        let assist = Assist {
            id,
            label: Label::new(label.to_owned()),
            group: Some(GroupLabel("Apply SSR".into())),
            target: comment_range,
            source_change,
            command: None,
        };

        ssr_assists.push(assist);
    }

    ssr_assists
}

#[cfg(test)]
mod tests {
    use expect_test::expect;
    use ide_assists::{Assist, AssistResolveStrategy};
    use ide_db::{
        FileRange, FxHashSet, RootDatabase, base_db::salsa::Durability,
        symbol_index::SymbolsDatabase,
    };
    use test_fixture::WithFixture;
    use triomphe::Arc;

    use super::ssr_assists;

    fn get_assists(
        #[rust_analyzer::rust_fixture] ra_fixture: &str,
        resolve: AssistResolveStrategy,
    ) -> Vec<Assist> {
        let (mut db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
        let mut local_roots = FxHashSet::default();
        local_roots.insert(test_fixture::WORKSPACE);
        db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
        ssr_assists(
            &db,
            &resolve,
            FileRange { file_id: file_id.into(), range: range_or_offset.into() },
        )
    }

    #[test]
    fn not_applicable_comment_not_ssr() {
        let ra_fixture = r#"
            //- /lib.rs

            // This is foo $0
            fn foo() {}
            "#;
        let assists = get_assists(ra_fixture, AssistResolveStrategy::All);

        assert_eq!(0, assists.len());
    }

    #[test]
    fn resolve_edits_true() {
        let assists = get_assists(
            r#"
            //- /lib.rs
            mod bar;

            // 2 ==>> 3$0
            fn foo() { 2 }

            //- /bar.rs
            fn bar() { 2 }
            "#,
            AssistResolveStrategy::All,
        );

        assert_eq!(2, assists.len());
        let mut assists = assists.into_iter();

        let apply_in_file_assist = assists.next().unwrap();
        expect![[r#"
            Assist {
                id: AssistId(
                    "ssr",
                    RefactorRewrite,
                ),
                label: "Apply SSR in file",
                group: Some(
                    GroupLabel(
                        "Apply SSR",
                    ),
                ),
                target: 10..21,
                source_change: Some(
                    SourceChange {
                        source_file_edits: {
                            FileId(
                                0,
                            ): (
                                TextEdit {
                                    indels: [
                                        Indel {
                                            insert: "3",
                                            delete: 33..34,
                                        },
                                    ],
                                    annotation: None,
                                },
                                None,
                            ),
                        },
                        file_system_edits: [],
                        is_snippet: false,
                        annotations: {},
                        next_annotation_id: 0,
                    },
                ),
                command: None,
            }
        "#]]
        .assert_debug_eq(&apply_in_file_assist);

        let apply_in_workspace_assist = assists.next().unwrap();
        expect![[r#"
            Assist {
                id: AssistId(
                    "ssr",
                    RefactorRewrite,
                ),
                label: "Apply SSR in workspace",
                group: Some(
                    GroupLabel(
                        "Apply SSR",
                    ),
                ),
                target: 10..21,
                source_change: Some(
                    SourceChange {
                        source_file_edits: {
                            FileId(
                                0,
                            ): (
                                TextEdit {
                                    indels: [
                                        Indel {
                                            insert: "3",
                                            delete: 33..34,
                                        },
                                    ],
                                    annotation: None,
                                },
                                None,
                            ),
                            FileId(
                                1,
                            ): (
                                TextEdit {
                                    indels: [
                                        Indel {
                                            insert: "3",
                                            delete: 11..12,
                                        },
                                    ],
                                    annotation: None,
                                },
                                None,
                            ),
                        },
                        file_system_edits: [],
                        is_snippet: false,
                        annotations: {},
                        next_annotation_id: 0,
                    },
                ),
                command: None,
            }
        "#]]
        .assert_debug_eq(&apply_in_workspace_assist);
    }

    #[test]
    fn resolve_edits_false() {
        let assists = get_assists(
            r#"
            //- /lib.rs
            mod bar;

            // 2 ==>> 3$0
            fn foo() { 2 }

            //- /bar.rs
            fn bar() { 2 }
            "#,
            AssistResolveStrategy::None,
        );

        assert_eq!(2, assists.len());
        let mut assists = assists.into_iter();

        let apply_in_file_assist = assists.next().unwrap();
        expect![[r#"
            Assist {
                id: AssistId(
                    "ssr",
                    RefactorRewrite,
                ),
                label: "Apply SSR in file",
                group: Some(
                    GroupLabel(
                        "Apply SSR",
                    ),
                ),
                target: 10..21,
                source_change: None,
                command: None,
            }
        "#]]
        .assert_debug_eq(&apply_in_file_assist);

        let apply_in_workspace_assist = assists.next().unwrap();
        expect![[r#"
            Assist {
                id: AssistId(
                    "ssr",
                    RefactorRewrite,
                ),
                label: "Apply SSR in workspace",
                group: Some(
                    GroupLabel(
                        "Apply SSR",
                    ),
                ),
                target: 10..21,
                source_change: None,
                command: None,
            }
        "#]]
        .assert_debug_eq(&apply_in_workspace_assist);
    }
}
