use std::iter;

use either::Either;
use hir::{HasSource, HirFileIdExt, ModuleSource};
use ide_db::{
    assists::{AssistId, AssistKind},
    base_db::FileId,
    defs::{Definition, NameClass, NameRefClass},
    search::{FileReference, SearchScope},
    FxHashMap, FxHashSet,
};
use itertools::Itertools;
use smallvec::SmallVec;
use syntax::{
    algo::find_node_at_range,
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
        make, HasVisibility,
    },
    match_ast, ted, AstNode,
    SyntaxKind::{self, WHITESPACE},
    SyntaxNode, TextRange, TextSize,
};

use crate::{AssistContext, Assists};

use super::remove_unused_param::range_to_remove;

// Assist: extract_module
//
// Extracts a selected region as separate module. All the references, visibility and imports are
// resolved.
//
// ```
// $0fn foo(name: i32) -> i32 {
//     name + 1
// }$0
//
// fn bar(name: i32) -> i32 {
//     name + 2
// }
// ```
// ->
// ```
// mod modname {
//     pub(crate) fn foo(name: i32) -> i32 {
//         name + 1
//     }
// }
//
// fn bar(name: i32) -> i32 {
//     name + 2
// }
// ```
pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
    if ctx.has_empty_selection() {
        return None;
    }

    let node = ctx.covering_element();
    let node = match node {
        syntax::NodeOrToken::Node(n) => n,
        syntax::NodeOrToken::Token(t) => t.parent()?,
    };

    //If the selection is inside impl block, we need to place new module outside impl block,
    //as impl blocks cannot contain modules

    let mut impl_parent: Option<ast::Impl> = None;
    let mut impl_child_count: usize = 0;
    if let Some(parent_assoc_list) = node.parent() {
        if let Some(parent_impl) = parent_assoc_list.parent() {
            if let Some(impl_) = ast::Impl::cast(parent_impl) {
                impl_child_count = parent_assoc_list.children().count();
                impl_parent = Some(impl_);
            }
        }
    }

    let mut curr_parent_module: Option<ast::Module> = None;
    if let Some(mod_syn_opt) = node.ancestors().find(|it| ast::Module::can_cast(it.kind())) {
        curr_parent_module = ast::Module::cast(mod_syn_opt);
    }

    let mut module = extract_target(&node, ctx.selection_trimmed())?;
    if module.body_items.is_empty() {
        return None;
    }

    let old_item_indent = module.body_items[0].indent_level();

    acc.add(
        AssistId("extract_module", AssistKind::RefactorExtract),
        "Extract Module",
        module.text_range,
        |builder| {
            //This takes place in three steps:
            //
            //- Firstly, we will update the references(usages) e.g. converting a
            //  function call bar() to modname::bar(), and similarly for other items
            //
            //- Secondly, changing the visibility of each item inside the newly selected module
            //  i.e. making a fn a() {} to pub(crate) fn a() {}
            //
            //- Thirdly, resolving all the imports this includes removing paths from imports
            //  outside the module, shifting/cloning them inside new module, or shifting the imports, or making
            //  new import statements

            //We are getting item usages and record_fields together, record_fields
            //for change_visibility and usages for first point mentioned above in the process

            let (usages_to_be_processed, record_fields, use_stmts_to_be_inserted) =
                module.get_usages_and_record_fields(ctx);

            builder.edit_file(ctx.file_id());
            use_stmts_to_be_inserted.into_iter().for_each(|(_, use_stmt)| {
                builder.insert(ctx.selection_trimmed().end(), format!("\n{use_stmt}"));
            });

            let import_paths_to_be_removed = module.resolve_imports(curr_parent_module, ctx);
            module.change_visibility(record_fields);

            let module_def = generate_module_def(&impl_parent, &mut module, old_item_indent);

            let mut usages_to_be_processed_for_cur_file = vec![];
            for (file_id, usages) in usages_to_be_processed {
                if file_id == ctx.file_id() {
                    usages_to_be_processed_for_cur_file = usages;
                    continue;
                }
                builder.edit_file(file_id);
                for (text_range, usage) in usages {
                    builder.replace(text_range, usage)
                }
            }

            builder.edit_file(ctx.file_id());
            for (text_range, usage) in usages_to_be_processed_for_cur_file {
                builder.replace(text_range, usage);
            }

            if let Some(impl_) = impl_parent {
                // Remove complete impl block if it has only one child (as such it will be empty
                // after deleting that child)
                let node_to_be_removed = if impl_child_count == 1 {
                    impl_.syntax()
                } else {
                    //Remove selected node
                    &node
                };

                builder.delete(node_to_be_removed.text_range());
                // Remove preceding indentation from node
                if let Some(range) = indent_range_before_given_node(node_to_be_removed) {
                    builder.delete(range);
                }

                builder.insert(impl_.syntax().text_range().end(), format!("\n\n{module_def}"));
            } else {
                for import_path_text_range in import_paths_to_be_removed {
                    if module.text_range.intersect(import_path_text_range).is_some() {
                        module.text_range = module.text_range.cover(import_path_text_range);
                    } else {
                        builder.delete(import_path_text_range);
                    }
                }

                builder.replace(module.text_range, module_def)
            }
        },
    )
}

fn generate_module_def(
    parent_impl: &Option<ast::Impl>,
    module: &mut Module,
    old_indent: IndentLevel,
) -> String {
    let (items_to_be_processed, new_item_indent) = if parent_impl.is_some() {
        (Either::Left(module.body_items.iter()), old_indent + 2)
    } else {
        (Either::Right(module.use_items.iter().chain(module.body_items.iter())), old_indent + 1)
    };

    let mut body = items_to_be_processed
        .map(|item| item.indent(IndentLevel(1)))
        .map(|item| format!("{new_item_indent}{item}"))
        .join("\n\n");

    if let Some(self_ty) = parent_impl.as_ref().and_then(|imp| imp.self_ty()) {
        let impl_indent = old_indent + 1;
        body = format!("{impl_indent}impl {self_ty} {{\n{body}\n{impl_indent}}}");

        // Add the import for enum/struct corresponding to given impl block
        module.make_use_stmt_of_node_with_super(self_ty.syntax());
        for item in module.use_items.iter() {
            body = format!("{impl_indent}{item}\n\n{body}");
        }
    }

    let module_name = module.name;
    format!("mod {module_name} {{\n{body}\n{old_indent}}}")
}

#[derive(Debug)]
struct Module {
    text_range: TextRange,
    name: &'static str,
    /// All items except use items.
    body_items: Vec<ast::Item>,
    /// Use items are kept separately as they help when the selection is inside an impl block,
    /// we can directly take these items and keep them outside generated impl block inside
    /// generated module.
    use_items: Vec<ast::Item>,
}

fn extract_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Module> {
    let selected_nodes = node
        .children()
        .filter(|node| selection_range.contains_range(node.text_range()))
        .chain(iter::once(node.clone()));
    let (use_items, body_items) = selected_nodes
        .filter_map(ast::Item::cast)
        .partition(|item| matches!(item, ast::Item::Use(..)));

    Some(Module { text_range: selection_range, name: "modname", body_items, use_items })
}

impl Module {
    fn get_usages_and_record_fields(
        &self,
        ctx: &AssistContext<'_>,
    ) -> (FxHashMap<FileId, Vec<(TextRange, String)>>, Vec<SyntaxNode>, FxHashMap<TextSize, ast::Use>)
    {
        let mut adt_fields = Vec::new();
        let mut refs: FxHashMap<FileId, Vec<(TextRange, String)>> = FxHashMap::default();
        // use `TextSize` as key to avoid repeated use stmts
        let mut use_stmts_to_be_inserted = FxHashMap::default();

        //Here impl is not included as each item inside impl will be tied to the parent of
        //implementing block(a struct, enum, etc), if the parent is in selected module, it will
        //get updated by ADT section given below or if it is not, then we dont need to do any operation

        for item in &self.body_items {
            match_ast! {
                match (item.syntax()) {
                    ast::Adt(it) => {
                        if let Some( nod ) = ctx.sema.to_def(&it) {
                            let node_def = Definition::Adt(nod);
                            self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs, &mut use_stmts_to_be_inserted);

                            //Enum Fields are not allowed to explicitly specify pub, it is implied
                            match it {
                                ast::Adt::Struct(x) => {
                                    if let Some(field_list) = x.field_list() {
                                        match field_list {
                                            ast::FieldList::RecordFieldList(record_field_list) => {
                                                record_field_list.fields().for_each(|record_field| {
                                                    adt_fields.push(record_field.syntax().clone());
                                                });
                                            },
                                            ast::FieldList::TupleFieldList(tuple_field_list) => {
                                                tuple_field_list.fields().for_each(|tuple_field| {
                                                    adt_fields.push(tuple_field.syntax().clone());
                                                });
                                            },
                                        }
                                    }
                                },
                                ast::Adt::Union(x) => {
                                        if let Some(record_field_list) = x.record_field_list() {
                                            record_field_list.fields().for_each(|record_field| {
                                                    adt_fields.push(record_field.syntax().clone());
                                            });
                                        }
                                },
                                ast::Adt::Enum(_) => {},
                            }
                        }
                    },
                    ast::TypeAlias(it) => {
                        if let Some( nod ) = ctx.sema.to_def(&it) {
                            let node_def = Definition::TypeAlias(nod);
                            self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs, &mut use_stmts_to_be_inserted);
                        }
                    },
                    ast::Const(it) => {
                        if let Some( nod ) = ctx.sema.to_def(&it) {
                            let node_def = Definition::Const(nod);
                            self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs, &mut use_stmts_to_be_inserted);
                        }
                    },
                    ast::Static(it) => {
                        if let Some( nod ) = ctx.sema.to_def(&it) {
                            let node_def = Definition::Static(nod);
                            self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs, &mut use_stmts_to_be_inserted);
                        }
                    },
                    ast::Fn(it) => {
                        if let Some( nod ) = ctx.sema.to_def(&it) {
                            let node_def = Definition::Function(nod);
                            self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs, &mut use_stmts_to_be_inserted);
                        }
                    },
                    ast::Macro(it) => {
                        if let Some(nod) = ctx.sema.to_def(&it) {
                            self.expand_and_group_usages_file_wise(ctx, Definition::Macro(nod), &mut refs, &mut use_stmts_to_be_inserted);
                        }
                    },
                    _ => (),
                }
            }
        }

        (refs, adt_fields, use_stmts_to_be_inserted)
    }

    fn expand_and_group_usages_file_wise(
        &self,
        ctx: &AssistContext<'_>,
        node_def: Definition,
        refs_in_files: &mut FxHashMap<FileId, Vec<(TextRange, String)>>,
        use_stmts_to_be_inserted: &mut FxHashMap<TextSize, ast::Use>,
    ) {
        let mod_name = self.name;
        let covering_node = match ctx.covering_element() {
            syntax::NodeOrToken::Node(node) => node,
            syntax::NodeOrToken::Token(tok) => tok.parent().unwrap(), // won't panic
        };
        let out_of_sel = |node: &SyntaxNode| !self.text_range.contains_range(node.text_range());
        let mut use_stmts_set = FxHashSet::default();

        for (file_id, refs) in node_def.usages(&ctx.sema).all() {
            let source_file = ctx.sema.parse(file_id);
            let usages = refs.into_iter().filter_map(|FileReference { range, .. }| {
                // handle normal usages
                let name_ref = find_node_at_range::<ast::NameRef>(source_file.syntax(), range)?;

                if out_of_sel(name_ref.syntax()) {
                    let new_ref = format!("{mod_name}::{name_ref}");
                    return Some((range, new_ref));
                } else if let Some(use_) = name_ref.syntax().ancestors().find_map(ast::Use::cast) {
                    // handle usages in use_stmts which is in_sel
                    // check if `use` is top stmt in selection
                    if use_.syntax().parent().is_some_and(|parent| parent == covering_node)
                        && use_stmts_set.insert(use_.syntax().text_range().start())
                    {
                        let use_ = use_stmts_to_be_inserted
                            .entry(use_.syntax().text_range().start())
                            .or_insert_with(|| use_.clone_subtree().clone_for_update());
                        for seg in use_
                            .syntax()
                            .descendants()
                            .filter_map(ast::NameRef::cast)
                            .filter(|seg| seg.syntax().to_string() == name_ref.to_string())
                        {
                            let new_ref = make::path_from_text(&format!("{mod_name}::{seg}"))
                                .clone_for_update();
                            ted::replace(seg.syntax().parent()?, new_ref.syntax());
                        }
                    }
                }

                None
            });
            refs_in_files.entry(file_id).or_default().extend(usages);
        }
    }

    fn change_visibility(&mut self, record_fields: Vec<SyntaxNode>) {
        let (mut replacements, record_field_parents, impls) =
            get_replacements_for_visibility_change(&mut self.body_items, false);

        let mut impl_items = impls
            .into_iter()
            .flat_map(|impl_| impl_.syntax().descendants())
            .filter_map(ast::Item::cast)
            .collect_vec();

        let (mut impl_item_replacements, _, _) =
            get_replacements_for_visibility_change(&mut impl_items, true);

        replacements.append(&mut impl_item_replacements);

        for (_, field_owner) in record_field_parents {
            for desc in field_owner.descendants().filter_map(ast::RecordField::cast) {
                let is_record_field_present =
                    record_fields.clone().into_iter().any(|x| x.to_string() == desc.to_string());
                if is_record_field_present {
                    replacements.push((desc.visibility(), desc.syntax().clone()));
                }
            }
        }

        for (vis, syntax) in replacements {
            let item = syntax.children_with_tokens().find(|node_or_token| {
                match node_or_token.kind() {
                    // We're skipping comments, doc comments, and attribute macros that may precede the keyword
                    // that the visibility should be placed before.
                    SyntaxKind::COMMENT | SyntaxKind::ATTR | SyntaxKind::WHITESPACE => false,
                    _ => true,
                }
            });

            add_change_vis(vis, item);
        }
    }

    fn resolve_imports(
        &mut self,
        module: Option<ast::Module>,
        ctx: &AssistContext<'_>,
    ) -> Vec<TextRange> {
        let mut imports_to_remove = vec![];
        let mut node_set = FxHashSet::default();

        for item in self.body_items.clone() {
            item.syntax()
                .descendants()
                .filter_map(|x| {
                    if let Some(name) = ast::Name::cast(x.clone()) {
                        NameClass::classify(&ctx.sema, &name).and_then(|nc| match nc {
                            NameClass::Definition(def) => Some((name.syntax().clone(), def)),
                            _ => None,
                        })
                    } else if let Some(name_ref) = ast::NameRef::cast(x) {
                        NameRefClass::classify(&ctx.sema, &name_ref).and_then(|nc| match nc {
                            NameRefClass::Definition(def) => Some((name_ref.syntax().clone(), def)),
                            _ => None,
                        })
                    } else {
                        None
                    }
                })
                .for_each(|(node, def)| {
                    if node_set.insert(node.to_string()) {
                        if let Some(import) = self.process_def_in_sel(def, &node, &module, ctx) {
                            check_intersection_and_push(&mut imports_to_remove, import);
                        }
                    }
                })
        }

        imports_to_remove
    }

    fn process_def_in_sel(
        &mut self,
        def: Definition,
        use_node: &SyntaxNode,
        curr_parent_module: &Option<ast::Module>,
        ctx: &AssistContext<'_>,
    ) -> Option<TextRange> {
        //We only need to find in the current file
        let selection_range = ctx.selection_trimmed();
        let file_id = ctx.file_id();
        let usage_res = def.usages(&ctx.sema).in_scope(&SearchScope::single_file(file_id)).all();
        let file = ctx.sema.parse(file_id);

        // track uses which does not exists in `Use`
        let mut uses_exist_in_sel = false;
        let mut uses_exist_out_sel = false;
        'outside: for (_, refs) in usage_res.iter() {
            for x in refs
                .iter()
                .filter(|x| find_node_at_range::<ast::Use>(file.syntax(), x.range).is_none())
                .filter_map(|x| find_node_at_range::<ast::Path>(file.syntax(), x.range))
            {
                let in_selection = selection_range.contains_range(x.syntax().text_range());
                uses_exist_in_sel |= in_selection;
                uses_exist_out_sel |= !in_selection;

                if uses_exist_in_sel && uses_exist_out_sel {
                    break 'outside;
                }
            }
        }

        let (def_in_mod, def_out_sel) =
            check_def_in_mod_and_out_sel(def, ctx, curr_parent_module, selection_range, file_id);

        // Find use stmt that use def in current file
        let use_stmt: Option<ast::Use> = usage_res
            .into_iter()
            .filter(|(use_file_id, _)| *use_file_id == file_id)
            .flat_map(|(_, refs)| refs.into_iter().rev())
            .find_map(|fref| find_node_at_range(file.syntax(), fref.range));
        let use_stmt_not_in_sel = use_stmt.as_ref().is_some_and(|use_stmt| {
            !selection_range.contains_range(use_stmt.syntax().text_range())
        });

        let mut use_tree_paths: Option<Vec<ast::Path>> = None;
        //Exists inside and outside selection
        // - Use stmt for item is present -> get the use_tree_str and reconstruct the path in new
        // module
        // - Use stmt for item is not present ->
        //If it is not found, the definition is either ported inside new module or it stays
        //outside:
        //- Def is inside: Nothing to import
        //- Def is outside: Import it inside with super

        //Exists inside selection but not outside -> Check for the import of it in original module,
        //get the use_tree_str, reconstruct the use stmt in new module

        let mut import_path_to_be_removed: Option<TextRange> = None;
        if uses_exist_in_sel && uses_exist_out_sel {
            //Changes to be made only inside new module

            //If use_stmt exists, find the use_tree_str, reconstruct it inside new module
            //If not, insert a use stmt with super and the given nameref
            match self.process_use_stmt_for_import_resolve(use_stmt, use_node) {
                Some((use_tree_str, _)) => use_tree_paths = Some(use_tree_str),
                None if def_in_mod && def_out_sel => {
                    //Considered only after use_stmt is not present
                    //def_in_mod && def_out_sel | exists_outside_sel(exists_inside_sel =
                    //true for all cases)
                    // false | false -> Do nothing
                    // false | true -> If source is in selection -> nothing to do, If source is outside
                    // mod -> ust_stmt transversal
                    // true  | false -> super import insertion
                    // true  | true -> super import insertion
                    self.make_use_stmt_of_node_with_super(use_node);
                }
                None => {}
            }
        } else if uses_exist_in_sel && !uses_exist_out_sel {
            //Changes to be made inside new module, and remove import from outside

            if let Some((mut use_tree_str, text_range_opt)) =
                self.process_use_stmt_for_import_resolve(use_stmt, use_node)
            {
                if let Some(text_range) = text_range_opt {
                    import_path_to_be_removed = Some(text_range);
                }

                if def_in_mod && def_out_sel {
                    if let Some(first_path_in_use_tree) = use_tree_str.last() {
                        let first_path_in_use_tree_str = first_path_in_use_tree.to_string();
                        if !first_path_in_use_tree_str.contains("super")
                            && !first_path_in_use_tree_str.contains("crate")
                        {
                            let super_path = make::ext::ident_path("super");
                            use_tree_str.push(super_path);
                        }
                    }
                }

                use_tree_paths = Some(use_tree_str);
            } else if def_in_mod && def_out_sel {
                self.make_use_stmt_of_node_with_super(use_node);
            }
        }

        if let Some(mut use_tree_paths) = use_tree_paths {
            use_tree_paths.reverse();

            if uses_exist_out_sel || !uses_exist_in_sel || !def_in_mod || !def_out_sel {
                if let Some(first_path_in_use_tree) = use_tree_paths.first() {
                    if first_path_in_use_tree.to_string().contains("super") {
                        use_tree_paths.insert(0, make::ext::ident_path("super"));
                    }
                }
            }

            let is_item = matches!(
                def,
                Definition::Macro(_)
                    | Definition::Module(_)
                    | Definition::Function(_)
                    | Definition::Adt(_)
                    | Definition::Const(_)
                    | Definition::Static(_)
                    | Definition::Trait(_)
                    | Definition::TraitAlias(_)
                    | Definition::TypeAlias(_)
            );

            if (def_out_sel || !is_item) && use_stmt_not_in_sel {
                let use_ = make::use_(
                    None,
                    make::use_tree(make::join_paths(use_tree_paths), None, None, false),
                );
                self.use_items.insert(0, ast::Item::from(use_));
            }
        }

        import_path_to_be_removed
    }

    fn make_use_stmt_of_node_with_super(&mut self, node_syntax: &SyntaxNode) -> ast::Item {
        let super_path = make::ext::ident_path("super");
        let node_path = make::ext::ident_path(&node_syntax.to_string());
        let use_ = make::use_(
            None,
            make::use_tree(make::join_paths(vec![super_path, node_path]), None, None, false),
        );

        let item = ast::Item::from(use_);
        self.use_items.insert(0, item.clone());
        item
    }

    fn process_use_stmt_for_import_resolve(
        &self,
        use_stmt: Option<ast::Use>,
        node_syntax: &SyntaxNode,
    ) -> Option<(Vec<ast::Path>, Option<TextRange>)> {
        let use_stmt = use_stmt?;
        for path_seg in use_stmt.syntax().descendants().filter_map(ast::PathSegment::cast) {
            if path_seg.syntax().to_string() == node_syntax.to_string() {
                let mut use_tree_str = vec![path_seg.parent_path()];
                get_use_tree_paths_from_path(path_seg.parent_path(), &mut use_tree_str);

                //Here we are looking for use_tree with same string value as node
                //passed above as the range_to_remove function looks for a comma and
                //then includes it in the text range to remove it. But the comma only
                //appears at the use_tree level
                for use_tree in path_seg.syntax().ancestors().filter_map(ast::UseTree::cast) {
                    if use_tree.syntax().to_string() == node_syntax.to_string() {
                        return Some((use_tree_str, Some(range_to_remove(use_tree.syntax()))));
                    }
                }

                return Some((use_tree_str, None));
            }
        }

        None
    }
}

fn check_intersection_and_push(
    import_paths_to_be_removed: &mut Vec<TextRange>,
    mut import_path: TextRange,
) {
    // Text ranges received here for imports are extended to the
    // next/previous comma which can cause intersections among them
    // and later deletion of these can cause panics similar
    // to reported in #11766. So to mitigate it, we
    // check for intersection between all current members
    // and combine all such ranges into one.
    let s: SmallVec<[_; 2]> = import_paths_to_be_removed
        .iter_mut()
        .positions(|it| it.intersect(import_path).is_some())
        .collect();
    for pos in s.into_iter().rev() {
        let intersecting_path = import_paths_to_be_removed.swap_remove(pos);
        import_path = import_path.cover(intersecting_path);
    }
    import_paths_to_be_removed.push(import_path);
}

fn check_def_in_mod_and_out_sel(
    def: Definition,
    ctx: &AssistContext<'_>,
    curr_parent_module: &Option<ast::Module>,
    selection_range: TextRange,
    curr_file_id: FileId,
) -> (bool, bool) {
    macro_rules! check_item {
        ($x:ident) => {
            if let Some(source) = $x.source(ctx.db()) {
                let have_same_parent = if let Some(ast_module) = &curr_parent_module {
                    ctx.sema.to_module_def(ast_module).is_some_and(|it| it == $x.module(ctx.db()))
                } else {
                    source.file_id.original_file(ctx.db()) == curr_file_id
                };

                let in_sel = !selection_range.contains_range(source.value.syntax().text_range());
                return (have_same_parent, in_sel);
            }
        };
    }

    match def {
        Definition::Module(x) => {
            let source = x.definition_source(ctx.db());
            let have_same_parent = match (&curr_parent_module, x.parent(ctx.db())) {
                (Some(ast_module), Some(hir_module)) => {
                    ctx.sema.to_module_def(ast_module).is_some_and(|it| it == hir_module)
                }
                _ => source.file_id.original_file(ctx.db()) == curr_file_id,
            };

            if have_same_parent {
                if let ModuleSource::Module(module_) = source.value {
                    let in_sel = !selection_range.contains_range(module_.syntax().text_range());
                    return (have_same_parent, in_sel);
                }
            }

            return (have_same_parent, false);
        }
        Definition::Function(x) => check_item!(x),
        Definition::Adt(x) => check_item!(x),
        Definition::Variant(x) => check_item!(x),
        Definition::Const(x) => check_item!(x),
        Definition::Static(x) => check_item!(x),
        Definition::Trait(x) => check_item!(x),
        Definition::TypeAlias(x) => check_item!(x),
        _ => {}
    }

    (false, false)
}

fn get_replacements_for_visibility_change(
    items: &mut [ast::Item],
    is_clone_for_updated: bool,
) -> (
    Vec<(Option<ast::Visibility>, SyntaxNode)>,
    Vec<(Option<ast::Visibility>, SyntaxNode)>,
    Vec<ast::Impl>,
) {
    let mut replacements = Vec::new();
    let mut record_field_parents = Vec::new();
    let mut impls = Vec::new();

    for item in items {
        if !is_clone_for_updated {
            *item = item.clone_for_update();
        }
        //Use stmts are ignored
        macro_rules! push_to_replacement {
            ($it:ident) => {
                replacements.push(($it.visibility(), $it.syntax().clone()))
            };
        }

        match item {
            ast::Item::Const(it) => push_to_replacement!(it),
            ast::Item::Enum(it) => push_to_replacement!(it),
            ast::Item::ExternCrate(it) => push_to_replacement!(it),
            ast::Item::Fn(it) => push_to_replacement!(it),
            //Associated item's visibility should not be changed
            ast::Item::Impl(it) if it.for_token().is_none() => impls.push(it.clone()),
            ast::Item::MacroDef(it) => push_to_replacement!(it),
            ast::Item::Module(it) => push_to_replacement!(it),
            ast::Item::Static(it) => push_to_replacement!(it),
            ast::Item::Struct(it) => {
                push_to_replacement!(it);
                record_field_parents.push((it.visibility(), it.syntax().clone()));
            }
            ast::Item::Trait(it) => push_to_replacement!(it),
            ast::Item::TypeAlias(it) => push_to_replacement!(it),
            ast::Item::Union(it) => {
                push_to_replacement!(it);
                record_field_parents.push((it.visibility(), it.syntax().clone()));
            }
            _ => (),
        }
    }

    (replacements, record_field_parents, impls)
}

fn get_use_tree_paths_from_path(
    path: ast::Path,
    use_tree_str: &mut Vec<ast::Path>,
) -> Option<&mut Vec<ast::Path>> {
    path.syntax()
        .ancestors()
        .filter(|x| x.to_string() != path.to_string())
        .filter_map(ast::UseTree::cast)
        .find_map(|use_tree| {
            if let Some(upper_tree_path) = use_tree.path() {
                if upper_tree_path.to_string() != path.to_string() {
                    use_tree_str.push(upper_tree_path.clone());
                    get_use_tree_paths_from_path(upper_tree_path, use_tree_str);
                    return Some(use_tree);
                }
            }
            None
        })?;

    Some(use_tree_str)
}

fn add_change_vis(vis: Option<ast::Visibility>, node_or_token_opt: Option<syntax::SyntaxElement>) {
    if vis.is_none() {
        if let Some(node_or_token) = node_or_token_opt {
            let pub_crate_vis = make::visibility_pub_crate().clone_for_update();
            ted::insert(ted::Position::before(node_or_token), pub_crate_vis.syntax());
        }
    }
}

fn indent_range_before_given_node(node: &SyntaxNode) -> Option<TextRange> {
    node.siblings_with_tokens(syntax::Direction::Prev)
        .find(|x| x.kind() == WHITESPACE)
        .map(|x| x.text_range())
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn test_not_applicable_without_selection() {
        check_assist_not_applicable(
            extract_module,
            r"
$0pub struct PublicStruct {
    field: i32,
}
            ",
        )
    }

    #[test]
    fn test_extract_module() {
        check_assist(
            extract_module,
            r"
            mod thirdpartycrate {
                pub mod nest {
                    pub struct SomeType;
                    pub struct SomeType2;
                }
                pub struct SomeType1;
            }

            mod bar {
                use crate::thirdpartycrate::{nest::{SomeType, SomeType2}, SomeType1};

                pub struct PublicStruct {
                    field: PrivateStruct,
                    field1: SomeType1,
                }

                impl PublicStruct {
                    pub fn new() -> Self {
                        Self { field: PrivateStruct::new(), field1: SomeType1 }
                    }
                }

                fn foo() {
                    let _s = PrivateStruct::new();
                    let _a = bar();
                }

$0struct PrivateStruct {
    inner: SomeType,
}

pub struct PrivateStruct1 {
    pub inner: i32,
}

impl PrivateStruct {
    fn new() -> Self {
         PrivateStruct { inner: SomeType }
    }
}

fn bar() -> i32 {
    2
}$0
            }
            ",
            r"
            mod thirdpartycrate {
                pub mod nest {
                    pub struct SomeType;
                    pub struct SomeType2;
                }
                pub struct SomeType1;
            }

            mod bar {
                use crate::thirdpartycrate::{nest::{SomeType2}, SomeType1};

                pub struct PublicStruct {
                    field: modname::PrivateStruct,
                    field1: SomeType1,
                }

                impl PublicStruct {
                    pub fn new() -> Self {
                        Self { field: modname::PrivateStruct::new(), field1: SomeType1 }
                    }
                }

                fn foo() {
                    let _s = modname::PrivateStruct::new();
                    let _a = modname::bar();
                }

mod modname {
    use crate::thirdpartycrate::nest::SomeType;

    pub(crate) struct PrivateStruct {
        pub(crate) inner: SomeType,
    }

    pub struct PrivateStruct1 {
        pub inner: i32,
    }

    impl PrivateStruct {
        pub(crate) fn new() -> Self {
             PrivateStruct { inner: SomeType }
        }
    }

    pub(crate) fn bar() -> i32 {
        2
    }
}
            }
            ",
        );
    }

    #[test]
    fn test_extract_module_for_function_only() {
        check_assist(
            extract_module,
            r"
$0fn foo(name: i32) -> i32 {
    name + 1
}$0

                fn bar(name: i32) -> i32 {
                    name + 2
                }
            ",
            r"
mod modname {
    pub(crate) fn foo(name: i32) -> i32 {
        name + 1
    }
}

                fn bar(name: i32) -> i32 {
                    name + 2
                }
            ",
        )
    }

    #[test]
    fn test_extract_module_for_impl_having_corresponding_adt_in_selection() {
        check_assist(
            extract_module,
            r"
            mod impl_play {
$0struct A {}

impl A {
    pub fn new_a() -> i32 {
        2
    }
}$0

                fn a() {
                    let _a = A::new_a();
                }
            }
            ",
            r"
            mod impl_play {
mod modname {
    pub(crate) struct A {}

    impl A {
        pub fn new_a() -> i32 {
            2
        }
    }
}

                fn a() {
                    let _a = modname::A::new_a();
                }
            }
            ",
        )
    }

    #[test]
    fn test_import_resolve_when_its_only_inside_selection() {
        check_assist(
            extract_module,
            r"
            mod foo {
                pub struct PrivateStruct;
                pub struct PrivateStruct1;
            }

            mod bar {
                use super::foo::{PrivateStruct, PrivateStruct1};

$0struct Strukt {
    field: PrivateStruct,
}$0

                struct Strukt1 {
                    field: PrivateStruct1,
                }
            }
            ",
            r"
            mod foo {
                pub struct PrivateStruct;
                pub struct PrivateStruct1;
            }

            mod bar {
                use super::foo::{PrivateStruct1};

mod modname {
    use super::super::foo::PrivateStruct;

    pub(crate) struct Strukt {
        pub(crate) field: PrivateStruct,
    }
}

                struct Strukt1 {
                    field: PrivateStruct1,
                }
            }
            ",
        )
    }

    #[test]
    fn test_import_resolve_when_its_inside_and_outside_selection_and_source_not_in_same_mod() {
        check_assist(
            extract_module,
            r"
            mod foo {
                pub struct PrivateStruct;
            }

            mod bar {
                use super::foo::PrivateStruct;

$0struct Strukt {
    field: PrivateStruct,
}$0

                struct Strukt1 {
                    field: PrivateStruct,
                }
            }
            ",
            r"
            mod foo {
                pub struct PrivateStruct;
            }

            mod bar {
                use super::foo::PrivateStruct;

mod modname {
    use super::super::foo::PrivateStruct;

    pub(crate) struct Strukt {
        pub(crate) field: PrivateStruct,
    }
}

                struct Strukt1 {
                    field: PrivateStruct,
                }
            }
            ",
        )
    }

    #[test]
    fn test_import_resolve_when_its_inside_and_outside_selection_and_source_is_in_same_mod() {
        check_assist(
            extract_module,
            r"
            mod bar {
                pub struct PrivateStruct;

$0struct Strukt {
   field: PrivateStruct,
}$0

                struct Strukt1 {
                    field: PrivateStruct,
                }
            }
            ",
            r"
            mod bar {
                pub struct PrivateStruct;

mod modname {
    use super::PrivateStruct;

    pub(crate) struct Strukt {
       pub(crate) field: PrivateStruct,
    }
}

                struct Strukt1 {
                    field: PrivateStruct,
                }
            }
            ",
        )
    }

    #[test]
    fn test_extract_module_for_corresponding_adt_of_impl_present_in_same_mod_but_not_in_selection()
    {
        check_assist(
            extract_module,
            r"
            mod impl_play {
                struct A {}

$0impl A {
    pub fn new_a() -> i32 {
        2
    }
}$0

                fn a() {
                    let _a = A::new_a();
                }
            }
            ",
            r"
            mod impl_play {
                struct A {}

mod modname {
    use super::A;

    impl A {
        pub fn new_a() -> i32 {
            2
        }
    }
}

                fn a() {
                    let _a = A::new_a();
                }
            }
            ",
        )
    }

    #[test]
    fn test_extract_module_for_impl_not_having_corresponding_adt_in_selection_and_not_in_same_mod_but_with_super(
    ) {
        check_assist(
            extract_module,
            r"
            mod foo {
                pub struct A {}
            }
            mod impl_play {
                use super::foo::A;

$0impl A {
    pub fn new_a() -> i32 {
        2
    }
}$0

                fn a() {
                    let _a = A::new_a();
                }
            }
            ",
            r"
            mod foo {
                pub struct A {}
            }
            mod impl_play {
                use super::foo::A;

mod modname {
    use super::super::foo::A;

    impl A {
        pub fn new_a() -> i32 {
            2
        }
    }
}

                fn a() {
                    let _a = A::new_a();
                }
            }
            ",
        )
    }

    #[test]
    fn test_import_resolve_for_trait_bounds_on_function() {
        check_assist(
            extract_module,
            r"
            mod impl_play2 {
                trait JustATrait {}

$0struct A {}

fn foo<T: JustATrait>(arg: T) -> T {
    arg
}

impl JustATrait for A {}

fn bar() {
    let a = A {};
    foo(a);
}$0
            }
            ",
            r"
            mod impl_play2 {
                trait JustATrait {}

mod modname {
    use super::JustATrait;

    pub(crate) struct A {}

    pub(crate) fn foo<T: JustATrait>(arg: T) -> T {
        arg
    }

    impl JustATrait for A {}

    pub(crate) fn bar() {
        let a = A {};
        foo(a);
    }
}
            }
            ",
        )
    }

    #[test]
    fn test_extract_module_for_module() {
        check_assist(
            extract_module,
            r"
            mod impl_play2 {
$0mod impl_play {
    pub struct A {}
}$0
            }
            ",
            r"
            mod impl_play2 {
mod modname {
    pub(crate) mod impl_play {
        pub struct A {}
    }
}
            }
            ",
        )
    }

    #[test]
    fn test_extract_module_with_multiple_files() {
        check_assist(
            extract_module,
            r"
            //- /main.rs
            mod foo;

            use foo::PrivateStruct;

            pub struct Strukt {
                field: PrivateStruct,
            }

            fn main() {
                $0struct Strukt1 {
                    field: Strukt,
                }$0
            }
            //- /foo.rs
            pub struct PrivateStruct;
            ",
            r"
            mod foo;

            use foo::PrivateStruct;

            pub struct Strukt {
                field: PrivateStruct,
            }

            fn main() {
                mod modname {
                    use super::Strukt;

                    pub(crate) struct Strukt1 {
                        pub(crate) field: Strukt,
                    }
                }
            }
            ",
        )
    }

    #[test]
    fn test_extract_module_macro_rules() {
        check_assist(
            extract_module,
            r"
$0macro_rules! m {
    () => {};
}$0
m! {}
            ",
            r"
mod modname {
    macro_rules! m {
        () => {};
    }
}
modname::m! {}
            ",
        );
    }

    #[test]
    fn test_do_not_apply_visibility_modifier_to_trait_impl_items() {
        check_assist(
            extract_module,
            r"
            trait ATrait {
                fn function();
            }

            struct A {}

$0impl ATrait for A {
    fn function() {}
}$0
            ",
            r"
            trait ATrait {
                fn function();
            }

            struct A {}

mod modname {
    use super::A;

    use super::ATrait;

    impl ATrait for A {
        fn function() {}
    }
}
            ",
        )
    }

    #[test]
    fn test_if_inside_impl_block_generate_module_outside() {
        check_assist(
            extract_module,
            r"
            struct A {}

            impl A {
$0fn foo() {}$0
                fn bar() {}
            }
        ",
            r"
            struct A {}

            impl A {
                fn bar() {}
            }

mod modname {
    use super::A;

    impl A {
        pub(crate) fn foo() {}
    }
}
        ",
        )
    }

    #[test]
    fn test_if_inside_impl_block_generate_module_outside_but_impl_block_having_one_child() {
        check_assist(
            extract_module,
            r"
            struct A {}
            struct B {}

            impl A {
$0fn foo(x: B) {}$0
            }
        ",
            r"
            struct A {}
            struct B {}

mod modname {
    use super::B;

    use super::A;

    impl A {
        pub(crate) fn foo(x: B) {}
    }
}
        ",
        )
    }

    #[test]
    fn test_issue_11766() {
        //https://github.com/rust-lang/rust-analyzer/issues/11766
        check_assist(
            extract_module,
            r"
            mod x {
                pub struct Foo;
                pub struct Bar;
            }

            use x::{Bar, Foo};

            $0type A = (Foo, Bar);$0
        ",
            r"
            mod x {
                pub struct Foo;
                pub struct Bar;
            }

            use x::{};

            mod modname {
                use super::x::Bar;

                use super::x::Foo;

                pub(crate) type A = (Foo, Bar);
            }
        ",
        )
    }

    #[test]
    fn test_issue_12790() {
        check_assist(
            extract_module,
            r"
            $0/// A documented function
            fn documented_fn() {}

            // A commented function with a #[] attribute macro
            #[cfg(test)]
            fn attribute_fn() {}

            // A normally commented function
            fn normal_fn() {}

            /// A documented Struct
            struct DocumentedStruct {
                // Normal field
                x: i32,

                /// Documented field
                y: i32,

                // Macroed field
                #[cfg(test)]
                z: i32,
            }

            // A macroed Struct
            #[cfg(test)]
            struct MacroedStruct {
                // Normal field
                x: i32,

                /// Documented field
                y: i32,

                // Macroed field
                #[cfg(test)]
                z: i32,
            }

            // A normal Struct
            struct NormalStruct {
                // Normal field
                x: i32,

                /// Documented field
                y: i32,

                // Macroed field
                #[cfg(test)]
                z: i32,
            }

            /// A documented type
            type DocumentedType = i32;

            // A macroed type
            #[cfg(test)]
            type MacroedType = i32;

            /// A module to move
            mod module {}

            /// An impl to move
            impl NormalStruct {
                /// A method
                fn new() {}
            }

            /// A documented trait
            trait DocTrait {
                /// Inner function
                fn doc() {}
            }

            /// An enum
            enum DocumentedEnum {
                /// A variant
                A,
                /// Another variant
                B { x: i32, y: i32 }
            }

            /// Documented const
            const MY_CONST: i32 = 0;$0
        ",
            r"
            mod modname {
                /// A documented function
                pub(crate) fn documented_fn() {}

                // A commented function with a #[] attribute macro
                #[cfg(test)]
                pub(crate) fn attribute_fn() {}

                // A normally commented function
                pub(crate) fn normal_fn() {}

                /// A documented Struct
                pub(crate) struct DocumentedStruct {
                    // Normal field
                    pub(crate) x: i32,

                    /// Documented field
                    pub(crate) y: i32,

                    // Macroed field
                    #[cfg(test)]
                    pub(crate) z: i32,
                }

                // A macroed Struct
                #[cfg(test)]
                pub(crate) struct MacroedStruct {
                    // Normal field
                    pub(crate) x: i32,

                    /// Documented field
                    pub(crate) y: i32,

                    // Macroed field
                    #[cfg(test)]
                    pub(crate) z: i32,
                }

                // A normal Struct
                pub(crate) struct NormalStruct {
                    // Normal field
                    pub(crate) x: i32,

                    /// Documented field
                    pub(crate) y: i32,

                    // Macroed field
                    #[cfg(test)]
                    pub(crate) z: i32,
                }

                /// A documented type
                pub(crate) type DocumentedType = i32;

                // A macroed type
                #[cfg(test)]
                pub(crate) type MacroedType = i32;

                /// A module to move
                pub(crate) mod module {}

                /// An impl to move
                impl NormalStruct {
                    /// A method
                    pub(crate) fn new() {}
                }

                /// A documented trait
                pub(crate) trait DocTrait {
                    /// Inner function
                    fn doc() {}
                }

                /// An enum
                pub(crate) enum DocumentedEnum {
                    /// A variant
                    A,
                    /// Another variant
                    B { x: i32, y: i32 }
                }

                /// Documented const
                pub(crate) const MY_CONST: i32 = 0;
            }
        ",
        )
    }

    #[test]
    fn test_merge_multiple_intersections() {
        check_assist(
            extract_module,
            r#"
mod dep {
    pub struct A;
    pub struct B;
    pub struct C;
}

use dep::{A, B, C};

$0struct S {
    inner: A,
    state: C,
    condvar: B,
}$0
"#,
            r#"
mod dep {
    pub struct A;
    pub struct B;
    pub struct C;
}

use dep::{};

mod modname {
    use super::dep::B;

    use super::dep::C;

    use super::dep::A;

    pub(crate) struct S {
        pub(crate) inner: A,
        pub(crate) state: C,
        pub(crate) condvar: B,
    }
}
"#,
        );
    }

    #[test]
    fn test_remove_import_path_inside_selection() {
        check_assist(
            extract_module,
            r#"
$0struct Point;
impl Point {
    pub const fn direction(self, other: Self) -> Option<Direction> {
        Some(Vertical)
    }
}

pub enum Direction {
    Horizontal,
    Vertical,
}
use Direction::{Horizontal, Vertical};$0

fn main() {
    let x = Vertical;
}
"#,
            r#"
mod modname {
    use Direction::{Horizontal, Vertical};

    pub(crate) struct Point;

    impl Point {
        pub const fn direction(self, other: Self) -> Option<Direction> {
            Some(Vertical)
        }
    }

    pub enum Direction {
        Horizontal,
        Vertical,
    }
}
use modname::Direction::{Horizontal, Vertical};

fn main() {
    let x = Vertical;
}
"#,
        );
    }
}
