use super::*;

// TODO: maybe manually define TypeDef here to include generics

macro_rules! tables {
    ($(($name:ident, $table:literal))+) => {
        $(
        #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
        pub struct $name(pub Row);
        impl AsRow for $name {
            const TABLE: usize = $table;
            fn to_row(&self) -> Row {
                self.0
            }
            fn from_row(row: Row) -> Self {
                $name(row)
            }
        }
    )*
    };
}

tables! {
    (AssemblyRef, 15)
    (Attribute, 1)
    (ClassLayout, 16)
    (Constant, 0)
    (Field, 2)
    (GenericParam, 3)
    (ImplMap, 11)
    (InterfaceImpl, 4)
    (MemberRef, 5)
    (MethodDef, 6)
    (Module, 14)
    (ModuleRef, 12)
    (NestedClass, 13)
    (Param, 7)
    (TypeDef, 8)
    (TypeRef, 9)
    (TypeSpec, 10)
}

impl Attribute {
    pub fn parent(&self) -> HasAttribute {
        self.decode(0)
    }

    pub fn ty(&self) -> AttributeType {
        self.decode(1)
    }

    pub fn name(&self) -> &'static str {
        let AttributeType::MemberRef(ctor) = self.ty();
        let MemberRefParent::TypeRef(ty) = ctor.parent();
        ty.name()
    }

    pub fn type_name(&self) -> TypeName {
        let AttributeType::MemberRef(ctor) = self.ty();
        let MemberRefParent::TypeRef(ty) = ctor.parent();
        ty.type_name()
    }

    pub fn args(&self) -> Vec<(&'static str, Value)> {
        let AttributeType::MemberRef(member) = self.ty();
        let mut sig = member.blob(2);
        let mut values = self.blob(2);
        let prolog = values.read_u16();
        std::debug_assert_eq!(prolog, 1);
        let this_and_gen_param_count = sig.read_usize();
        std::debug_assert_eq!(this_and_gen_param_count, 32);
        let fixed_arg_count = sig.read_usize();
        let ret_type = sig.read_usize();
        std::debug_assert_eq!(ret_type, 1);
        let mut args = Vec::with_capacity(fixed_arg_count);
        let reader = self.reader();

        for _ in 0..fixed_arg_count {
            let arg = match reader.type_from_blob(&mut sig, None, &[]) {
                Type::Bool => Value::Bool(values.read_bool()),
                Type::I8 => Value::I8(values.read_i8()),
                Type::U8 => Value::U8(values.read_u8()),
                Type::I16 => Value::I16(values.read_i16()),
                Type::U16 => Value::U16(values.read_u16()),
                Type::I32 => Value::I32(values.read_i32()),
                Type::U32 => Value::U32(values.read_u32()),
                Type::I64 => Value::I64(values.read_i64()),
                Type::U64 => Value::U64(values.read_u64()),
                Type::String => Value::String(values.read_str().to_string()),
                Type::Name(TypeName::Type) => Value::TypeName(TypeName::parse(values.read_str())),
                Type::TypeDef(def, _) => {
                    Value::EnumDef(def, Box::new(values.read_integer(def.underlying_type())))
                }
                rest => unimplemented!("{rest:?}"),
            };

            args.push(("", arg));
        }

        let named_arg_count = values.read_u16();
        args.reserve(named_arg_count as usize);

        for _ in 0..named_arg_count {
            let _id = values.read_u8();
            let arg_type = values.read_u8();
            let mut name = values.read_str();
            let arg = match arg_type {
                ELEMENT_TYPE_BOOLEAN => Value::Bool(values.read_bool()),
                ELEMENT_TYPE_I2 => Value::I16(values.read_i16()),
                ELEMENT_TYPE_I4 => Value::I32(values.read_i32()),
                ELEMENT_TYPE_U4 => Value::U32(values.read_u32()),
                ELEMENT_TYPE_STRING => Value::String(values.read_str().to_string()),
                0x50 => Value::TypeName(TypeName::parse(values.read_str())),
                0x55 => {
                    let type_name = TypeName::parse(name);
                    let def = reader
                        .get_type_def(type_name.namespace(), type_name.name())
                        .next()
                        .expect("Type not found");
                    name = values.read_str();
                    Value::EnumDef(def, Box::new(values.read_integer(def.underlying_type())))
                }
                rest => unimplemented!("{rest:?}"),
            };
            args.push((name, arg));
        }

        debug_assert_eq!(sig.slice.len(), 0);
        debug_assert_eq!(values.slice.len(), 0);

        args
    }
}

impl ClassLayout {
    pub fn packing_size(&self) -> usize {
        self.usize(0)
    }
}

impl Constant {
    pub fn ty(&self) -> Type {
        Type::from_code(self.usize(0)).expect("Constant type not found")
    }

    pub fn value(&self) -> Value {
        let mut blob = self.blob(2);

        match self.ty() {
            Type::I8 => Value::I8(blob.read_i8()),
            Type::U8 => Value::U8(blob.read_u8()),
            Type::I16 => Value::I16(blob.read_i16()),
            Type::U16 => Value::U16(blob.read_u16()),
            Type::I32 => Value::I32(blob.read_i32()),
            Type::U32 => Value::U32(blob.read_u32()),
            Type::I64 => Value::I64(blob.read_i64()),
            Type::U64 => Value::U64(blob.read_u64()),
            Type::F32 => Value::F32(blob.read_f32()),
            Type::F64 => Value::F64(blob.read_f64()),
            Type::String => Value::String(blob.read_string()),
            rest => unimplemented!("{rest:?}"),
        }
    }
}

impl Field {
    pub fn flags(&self) -> FieldAttributes {
        FieldAttributes(self.usize(0) as u16)
    }

    pub fn name(&self) -> &'static str {
        self.str(1)
    }

    pub fn constant(&self) -> Option<Constant> {
        self.equal_range(1, HasConstant::Field(*self).encode())
            .next()
    }

    // TODO: enclosing craziness is only needed for nested structs - get rid of those in riddle and this goes away.
    pub fn ty(&self, enclosing: Option<TypeDef>) -> Type {
        let mut blob = self.blob(2);
        blob.read_usize();
        blob.read_modifiers();
        let def = self.reader().type_from_blob(&mut blob, enclosing, &[]);

        if self.has_attribute("ConstAttribute") {
            def.to_const_type().to_const_ptr()
        } else {
            def
        }
    }
}

impl GenericParam {
    pub fn number(&self) -> u16 {
        self.usize(0) as u16
    }

    pub fn name(&self) -> &'static str {
        self.str(3)
    }
}

impl ImplMap {
    pub fn flags(&self) -> PInvokeAttributes {
        PInvokeAttributes(self.usize(0))
    }

    pub fn scope(&self) -> ModuleRef {
        ModuleRef(self.row(3))
    }

    pub fn import_name(&self) -> &'static str {
        self.str(2)
    }
}

impl InterfaceImpl {
    pub fn ty(&self, generics: &[Type]) -> Type {
        self.reader().type_from_ref(self.decode(1), None, generics)
    }
}

impl MemberRef {
    pub fn parent(&self) -> MemberRefParent {
        self.decode(0)
    }

    pub fn name(&self) -> &'static str {
        self.str(1)
    }

    pub fn signature(&self) -> MethodDefSig {
        let reader = self.reader();
        let mut blob = self.blob(2);
        let call_flags = MethodCallAttributes(blob.read_usize() as u8);
        let params = blob.read_usize();
        let return_type = reader.type_from_blob(&mut blob, None, &[]);

        MethodDefSig {
            call_flags,
            return_type,
            params: (0..params)
                .map(|_| reader.type_from_blob(&mut blob, None, &[]))
                .collect(),
        }
    }
}

impl MethodDef {
    pub fn impl_flags(&self) -> MethodImplAttributes {
        MethodImplAttributes(self.usize(1) as u16)
    }

    pub fn flags(&self) -> MethodAttributes {
        MethodAttributes(self.usize(2) as u16)
    }

    pub fn name(&self) -> &'static str {
        self.str(3)
    }

    pub fn params(&self) -> RowIterator<Param> {
        self.list(5)
    }

    pub fn impl_map(&self) -> Option<ImplMap> {
        self.equal_range(1, MemberForwarded::MethodDef(*self).encode())
            .next()
    }

    pub fn module_name(&self) -> &'static str {
        self.impl_map().map_or("", |map| map.scope().name())
    }

    pub fn signature(&self, generics: &[Type]) -> MethodDefSig {
        let reader = self.reader();
        let mut blob = self.blob(4);
        let call_flags = MethodCallAttributes(blob.read_usize() as u8);
        let params = blob.read_usize();
        let return_type = reader.type_from_blob(&mut blob, None, generics);

        MethodDefSig {
            call_flags,
            return_type,
            params: (0..params)
                .map(|_| reader.type_from_blob(&mut blob, None, generics))
                .collect(),
        }
    }
}

impl ModuleRef {
    pub fn name(&self) -> &'static str {
        self.str(0)
    }
}

impl NestedClass {
    pub fn inner(&self) -> TypeDef {
        TypeDef(self.row(0))
    }

    pub fn outer(&self) -> TypeDef {
        TypeDef(self.row(1))
    }
}

impl Param {
    pub fn flags(&self) -> ParamAttributes {
        ParamAttributes(self.usize(0) as u16)
    }

    pub fn sequence(&self) -> u16 {
        self.usize(1) as u16
    }

    pub fn name(&self) -> &'static str {
        self.str(2)
    }
}

impl TypeDef {
    pub fn flags(&self) -> TypeAttributes {
        TypeAttributes(self.usize(0) as u32)
    }

    pub fn name(&self) -> &'static str {
        trim_tick(self.str(1))
    }

    pub fn namespace(&self) -> &'static str {
        self.str(2)
    }

    pub fn type_name(&self) -> TypeName {
        TypeName(self.namespace(), self.name())
    }

    pub fn extends(&self) -> Option<TypeName> {
        let extends = self.usize(3);

        if extends == 0 {
            return None;
        }

        Some(TypeDefOrRef::decode(self.file(), extends).type_name())
    }

    pub fn methods(&self) -> RowIterator<MethodDef> {
        self.list(5)
    }

    pub fn fields(&self) -> RowIterator<Field> {
        self.list(4)
    }

    pub fn generics(&self) -> RowIterator<GenericParam> {
        self.equal_range(2, TypeOrMethodDef::TypeDef(*self).encode())
    }

    pub fn interface_impls(&self) -> RowIterator<InterfaceImpl> {
        self.equal_range(0, self.index() + 1)
    }

    pub fn enclosing_type(&self) -> Option<TypeDef> {
        self.equal_range::<NestedClass>(0, self.index() + 1)
            .next()
            .map(|row| TypeDef(row.row(1)))
    }

    pub fn class_layout(&self) -> Option<ClassLayout> {
        self.equal_range(2, self.index() + 1).next()
    }

    pub fn underlying_type(&self) -> Type {
        let field = self.fields().next().expect("Field not found");
        if let Some(constant) = field.constant() {
            constant.ty()
        } else {
            field.ty(Some(*self))
        }
    }

    pub fn kind(&self) -> TypeKind {
        match self.extends() {
            None => TypeKind::Interface,
            Some(TypeName::Enum) => TypeKind::Enum,
            Some(TypeName::Delegate) => TypeKind::Delegate,
            Some(TypeName::Struct) => TypeKind::Struct,
            Some(_) => TypeKind::Class,
        }
    }

    pub fn size(&self) -> usize {
        match self.kind() {
            TypeKind::Struct => {
                if self.flags().contains(TypeAttributes::ExplicitLayout) {
                    self.fields()
                        .map(|field| field.ty(Some(*self)).size())
                        .max()
                        .unwrap_or(1)
                } else {
                    let mut sum = 0;
                    for field in self.fields() {
                        let ty = field.ty(Some(*self));
                        let size = ty.size();
                        let align = ty.align();
                        sum = (sum + (align - 1)) & !(align - 1);
                        sum += size;
                    }
                    sum
                }
            }
            TypeKind::Enum => self.underlying_type().size(),
            _ => 4,
        }
    }

    pub fn align(&self) -> usize {
        match self.kind() {
            TypeKind::Struct => self
                .fields()
                .map(|field| field.ty(Some(*self)).align())
                .max()
                .unwrap_or(1),
            TypeKind::Enum => self.underlying_type().align(),
            _ => 4,
        }
    }
}

impl TypeRef {
    pub fn name(&self) -> &'static str {
        trim_tick(self.str(1))
    }

    pub fn namespace(&self) -> &'static str {
        self.str(2)
    }

    pub fn type_name(&self) -> TypeName {
        TypeName(self.namespace(), self.name())
    }

    pub fn resolution_scope(&self) -> ResolutionScope {
        self.decode(0)
    }
}

fn trim_tick(name: &str) -> &str {
    if name.as_bytes().iter().rev().nth(1) == Some(&b'`') {
        &name[..name.len() - 2]
    } else {
        name
    }
}
