use crate::{
    Function, FunctionKind, InterfaceId, Resolve, Type, TypeDef, TypeDefKind, TypeId, WorldId,
    WorldItem,
};
use indexmap::IndexSet;

#[derive(Default)]
pub struct LiveTypes {
    set: IndexSet<TypeId>,
}

impl LiveTypes {
    pub fn iter(&self) -> impl Iterator<Item = TypeId> + '_ {
        self.set.iter().copied()
    }

    pub fn len(&self) -> usize {
        self.set.len()
    }

    pub fn add_interface(&mut self, resolve: &Resolve, iface: InterfaceId) {
        self.visit_interface(resolve, iface);
    }

    pub fn add_world(&mut self, resolve: &Resolve, world: WorldId) {
        self.visit_world(resolve, world);
    }

    pub fn add_world_item(&mut self, resolve: &Resolve, item: &WorldItem) {
        self.visit_world_item(resolve, item);
    }

    pub fn add_func(&mut self, resolve: &Resolve, func: &Function) {
        self.visit_func(resolve, func);
    }

    pub fn add_type_id(&mut self, resolve: &Resolve, ty: TypeId) {
        self.visit_type_id(resolve, ty);
    }

    pub fn add_type(&mut self, resolve: &Resolve, ty: &Type) {
        self.visit_type(resolve, ty);
    }
}

impl TypeIdVisitor for LiveTypes {
    fn before_visit_type_id(&mut self, id: TypeId) -> bool {
        !self.set.contains(&id)
    }

    fn after_visit_type_id(&mut self, id: TypeId) {
        assert!(self.set.insert(id));
    }
}

/// Helper trait to walk the structure of a type and visit all `TypeId`s that
/// it refers to, possibly transitively.
pub trait TypeIdVisitor {
    /// Callback invoked just before a type is visited.
    ///
    /// If this function returns `false` the type is not visited, otherwise it's
    /// recursed into.
    fn before_visit_type_id(&mut self, id: TypeId) -> bool {
        let _ = id;
        true
    }

    /// Callback invoked once a type is finished being visited.
    fn after_visit_type_id(&mut self, id: TypeId) {
        let _ = id;
    }

    fn visit_interface(&mut self, resolve: &Resolve, iface: InterfaceId) {
        let iface = &resolve.interfaces[iface];
        for (_, id) in iface.types.iter() {
            self.visit_type_id(resolve, *id);
        }
        for (_, func) in iface.functions.iter() {
            self.visit_func(resolve, func);
        }
    }

    fn visit_world(&mut self, resolve: &Resolve, world: WorldId) {
        let world = &resolve.worlds[world];
        for (_, item) in world.imports.iter().chain(world.exports.iter()) {
            self.visit_world_item(resolve, item);
        }
    }

    fn visit_world_item(&mut self, resolve: &Resolve, item: &WorldItem) {
        match item {
            WorldItem::Interface { id, .. } => self.visit_interface(resolve, *id),
            WorldItem::Function(f) => self.visit_func(resolve, f),
            WorldItem::Type(t) => self.visit_type_id(resolve, *t),
        }
    }

    fn visit_func(&mut self, resolve: &Resolve, func: &Function) {
        match func.kind {
            // This resource is live as it's attached to a static method but
            // it's not guaranteed to be present in either params or results, so
            // be sure to attach it here.
            FunctionKind::Static(id) => self.visit_type_id(resolve, id),

            // The resource these are attached to is in the params/results, so
            // no need to re-add it here.
            FunctionKind::Method(_) | FunctionKind::Constructor(_) => {}

            FunctionKind::Freestanding => {}
        }

        for (_, ty) in func.params.iter() {
            self.visit_type(resolve, ty);
        }
        for ty in func.results.iter_types() {
            self.visit_type(resolve, ty);
        }
    }

    fn visit_type_id(&mut self, resolve: &Resolve, ty: TypeId) {
        if self.before_visit_type_id(ty) {
            self.visit_type_def(resolve, &resolve.types[ty]);
            self.after_visit_type_id(ty);
        }
    }

    fn visit_type_def(&mut self, resolve: &Resolve, ty: &TypeDef) {
        match &ty.kind {
            TypeDefKind::Type(t)
            | TypeDefKind::List(t)
            | TypeDefKind::Option(t)
            | TypeDefKind::Future(Some(t)) => self.visit_type(resolve, t),
            TypeDefKind::Handle(handle) => match handle {
                crate::Handle::Own(ty) => self.visit_type_id(resolve, *ty),
                crate::Handle::Borrow(ty) => self.visit_type_id(resolve, *ty),
            },
            TypeDefKind::Resource => {}
            TypeDefKind::Record(r) => {
                for field in r.fields.iter() {
                    self.visit_type(resolve, &field.ty);
                }
            }
            TypeDefKind::Tuple(r) => {
                for ty in r.types.iter() {
                    self.visit_type(resolve, ty);
                }
            }
            TypeDefKind::Variant(v) => {
                for case in v.cases.iter() {
                    if let Some(ty) = &case.ty {
                        self.visit_type(resolve, ty);
                    }
                }
            }
            TypeDefKind::Result(r) => {
                if let Some(ty) = &r.ok {
                    self.visit_type(resolve, ty);
                }
                if let Some(ty) = &r.err {
                    self.visit_type(resolve, ty);
                }
            }
            TypeDefKind::Stream(s) => {
                if let Some(ty) = &s.element {
                    self.visit_type(resolve, ty);
                }
                if let Some(ty) = &s.end {
                    self.visit_type(resolve, ty);
                }
            }
            TypeDefKind::Flags(_) | TypeDefKind::Enum(_) | TypeDefKind::Future(None) => {}
            TypeDefKind::Unknown => unreachable!(),
        }
    }

    fn visit_type(&mut self, resolve: &Resolve, ty: &Type) {
        match ty {
            Type::Id(id) => self.visit_type_id(resolve, *id),
            _ => {}
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{LiveTypes, Resolve};

    fn live(wit: &str, ty: &str) -> Vec<String> {
        let mut resolve = Resolve::default();
        resolve.push_str("test.wit", wit).unwrap();
        let (_, interface) = resolve.interfaces.iter().next_back().unwrap();
        let ty = interface.types[ty];
        let mut live = LiveTypes::default();
        live.add_type_id(&resolve, ty);

        live.iter()
            .filter_map(|ty| resolve.types[ty].name.clone())
            .collect()
    }

    #[test]
    fn no_deps() {
        let types = live(
            "
                package foo:bar;

                interface foo {
                    type t = u32;
                }
            ",
            "t",
        );
        assert_eq!(types, ["t"]);
    }

    #[test]
    fn one_dep() {
        let types = live(
            "
                package foo:bar;

                interface foo {
                    type t = u32;
                    type u = t;
                }
            ",
            "u",
        );
        assert_eq!(types, ["t", "u"]);
    }

    #[test]
    fn chain() {
        let types = live(
            "
                package foo:bar;

                interface foo {
                    resource t1;
                    record t2 {
                        x: t1,
                    }
                    variant t3 {
                        x(t2),
                    }
                    flags t4 { a }
                    enum t5 { a }
                    type t6 = tuple<t5, t4, t3>;
                }
            ",
            "t6",
        );
        assert_eq!(types, ["t5", "t4", "t1", "t2", "t3", "t6"]);
    }
}
