use super::Pass;
use crate::clean::*;
use crate::core::DocContext;
use crate::fold::DocFolder;

use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::sym;

pub const COLLECT_TRAIT_IMPLS: Pass = Pass {
    name: "collect-trait-impls",
    run: collect_trait_impls,
    description: "retrieves trait impls for items in the crate",
};

pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
    let mut synth = SyntheticImplCollector::new(cx);
    let mut krate = synth.fold_crate(krate);

    let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();

    let crate_items = {
        let mut coll = ItemCollector::new();
        krate = coll.fold_crate(krate);
        coll.items
    };

    let mut new_items = Vec::new();

    for &cnum in cx.tcx.crates().iter() {
        for &did in cx.tcx.all_trait_implementations(cnum).iter() {
            inline::build_impl(cx, did, None, &mut new_items);
        }
    }

    // Also try to inline primitive impls from other crates.
    let lang_items = cx.tcx.lang_items();
    let primitive_impls = [
        lang_items.isize_impl(),
        lang_items.i8_impl(),
        lang_items.i16_impl(),
        lang_items.i32_impl(),
        lang_items.i64_impl(),
        lang_items.i128_impl(),
        lang_items.usize_impl(),
        lang_items.u8_impl(),
        lang_items.u16_impl(),
        lang_items.u32_impl(),
        lang_items.u64_impl(),
        lang_items.u128_impl(),
        lang_items.f32_impl(),
        lang_items.f64_impl(),
        lang_items.f32_runtime_impl(),
        lang_items.f64_runtime_impl(),
        lang_items.bool_impl(),
        lang_items.char_impl(),
        lang_items.str_impl(),
        lang_items.slice_impl(),
        lang_items.slice_u8_impl(),
        lang_items.str_alloc_impl(),
        lang_items.slice_alloc_impl(),
        lang_items.slice_u8_alloc_impl(),
        lang_items.const_ptr_impl(),
        lang_items.mut_ptr_impl(),
        lang_items.const_slice_ptr_impl(),
        lang_items.mut_slice_ptr_impl(),
    ];

    for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
        if !def_id.is_local() {
            inline::build_impl(cx, def_id, None, &mut new_items);

            // FIXME(eddyb) is this `doc(hidden)` check needed?
            if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
                let self_ty = cx.tcx.type_of(def_id);
                let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
                let mut renderinfo = cx.renderinfo.borrow_mut();

                new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id)));
            }
        }
    }

    let mut cleaner = BadImplStripper { prims, items: crate_items };

    // scan through included items ahead of time to splice in Deref targets to the "valid" sets
    for it in &new_items {
        if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.inner {
            if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
                let target = items
                    .iter()
                    .find_map(|item| match item.inner {
                        TypedefItem(ref t, true) => Some(&t.type_),
                        _ => None,
                    })
                    .expect("Deref impl without Target type");

                if let Some(prim) = target.primitive_type() {
                    cleaner.prims.insert(prim);
                } else if let Some(did) = target.def_id() {
                    cleaner.items.insert(did);
                }
            }
        }
    }

    new_items.retain(|it| {
        if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.inner {
            cleaner.keep_item(for_)
                || trait_.as_ref().map_or(false, |t| cleaner.keep_item(t))
                || blanket_impl.is_some()
        } else {
            true
        }
    });

    // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
    // doesn't work with it anyway, so pull them from the HIR map instead
    for &trait_did in cx.tcx.all_traits(LOCAL_CRATE).iter() {
        for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
            let impl_did = cx.tcx.hir().local_def_id(impl_node);
            inline::build_impl(cx, impl_did.to_def_id(), None, &mut new_items);
        }
    }

    if let Some(ref mut it) = krate.module {
        if let ModuleItem(Module { ref mut items, .. }) = it.inner {
            items.extend(synth.impls);
            items.extend(new_items);
        } else {
            panic!("collect-trait-impls can't run");
        }
    } else {
        panic!("collect-trait-impls can't run");
    }

    krate
}

struct SyntheticImplCollector<'a, 'tcx> {
    cx: &'a DocContext<'tcx>,
    impls: Vec<Item>,
}

impl<'a, 'tcx> SyntheticImplCollector<'a, 'tcx> {
    fn new(cx: &'a DocContext<'tcx>) -> Self {
        SyntheticImplCollector { cx, impls: Vec::new() }
    }
}

impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        if i.is_struct() || i.is_enum() || i.is_union() {
            // FIXME(eddyb) is this `doc(hidden)` check needed?
            if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
                self.impls.extend(get_auto_trait_and_blanket_impls(
                    self.cx,
                    self.cx.tcx.type_of(i.def_id),
                    i.def_id,
                ));
            }
        }

        self.fold_item_recur(i)
    }
}

#[derive(Default)]
struct ItemCollector {
    items: FxHashSet<DefId>,
}

impl ItemCollector {
    fn new() -> Self {
        Self::default()
    }
}

impl DocFolder for ItemCollector {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        self.items.insert(i.def_id);

        self.fold_item_recur(i)
    }
}

struct BadImplStripper {
    prims: FxHashSet<PrimitiveType>,
    items: FxHashSet<DefId>,
}

impl BadImplStripper {
    fn keep_item(&self, ty: &Type) -> bool {
        if let Generic(_) = ty {
            // keep impls made on generics
            true
        } else if let Some(prim) = ty.primitive_type() {
            self.prims.contains(&prim)
        } else if let Some(did) = ty.def_id() {
            self.items.contains(&did)
        } else {
            false
        }
    }
}
