//! Item signature IR definitions

use std::ops::Not as _;

use bitflags::bitflags;
use cfg::{CfgExpr, CfgOptions};
use either::Either;
use hir_expand::{InFile, Intern, Lookup, name::Name};
use intern::{Symbol, sym};
use la_arena::{Arena, Idx};
use rustc_abi::{IntegerType, ReprOptions};
use syntax::{
    AstNode, SyntaxNodePtr,
    ast::{self, HasGenericParams, IsString},
};
use thin_vec::ThinVec;
use triomphe::Arc;

use crate::{
    ConstId, EnumId, EnumVariantId, EnumVariantLoc, FunctionId, HasModule, ImplId, ItemContainerId,
    ModuleId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, UnionId, VariantId,
    db::DefDatabase,
    expr_store::{
        ExpressionStore, ExpressionStoreSourceMap,
        lower::{
            ExprCollector, lower_function, lower_generic_params, lower_trait, lower_trait_alias,
            lower_type_alias,
        },
    },
    hir::{ExprId, PatId, generics::GenericParams},
    item_tree::{
        AttrOwner, Field, FieldParent, FieldsShape, FileItemTreeId, ItemTree, ItemTreeId, ModItem,
        RawVisibility, RawVisibilityId,
    },
    lang_item::LangItem,
    src::HasSource,
    type_ref::{TraitRef, TypeBound, TypeRef, TypeRefId},
};

#[derive(Debug, PartialEq, Eq)]
pub struct StructSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub flags: StructFlags,
    pub shape: FieldsShape,
    pub repr: Option<ReprOptions>,
}

bitflags! {
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct StructFlags: u8 {
        /// Indicates whether the struct has a `#[rustc_has_incoherent_inherent_impls]` attribute.
        const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1;
        /// Indicates whether the struct has a `#[fundamental]` attribute.
        const FUNDAMENTAL      = 1 << 2;
        /// Indicates whether the struct is `PhantomData`.
        const IS_PHANTOM_DATA  = 1 << 3;
        /// Indicates whether this struct is `Box`.
        const IS_BOX           = 1 << 4;
        /// Indicates whether this struct is `ManuallyDrop`.
        const IS_MANUALLY_DROP = 1 << 5;
        /// Indicates whether this struct is `UnsafeCell`.
        const IS_UNSAFE_CELL   = 1 << 6;
    }
}

impl StructSignature {
    pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);
        let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());

        let mut flags = StructFlags::empty();
        if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
            flags |= StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
        }
        if attrs.by_key(&sym::fundamental).exists() {
            flags |= StructFlags::FUNDAMENTAL;
        }
        if let Some(lang) = attrs.lang_item() {
            match lang {
                LangItem::PhantomData => flags |= StructFlags::IS_PHANTOM_DATA,
                LangItem::OwnedBox => flags |= StructFlags::IS_BOX,
                LangItem::ManuallyDrop => flags |= StructFlags::IS_MANUALLY_DROP,
                LangItem::UnsafeCell => flags |= StructFlags::IS_UNSAFE_CELL,
                _ => (),
            }
        }
        let repr = attrs.repr();

        let hir_expand::files::InFileWrapper { file_id, value } = loc.source(db);
        let (store, generic_params, source_map) = lower_generic_params(
            db,
            loc.container,
            id.into(),
            file_id,
            value.generic_param_list(),
            value.where_clause(),
        );
        (
            Arc::new(StructSignature {
                generic_params,
                store,
                flags,
                shape: item_tree[loc.id.value].shape,
                name: item_tree[loc.id.value].name.clone(),
                repr,
            }),
            Arc::new(source_map),
        )
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct UnionSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub flags: StructFlags,
    pub repr: Option<ReprOptions>,
}

impl UnionSignature {
    pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let krate = loc.container.krate;
        let item_tree = loc.id.item_tree(db);
        let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
        let mut flags = StructFlags::empty();
        if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
            flags |= StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
        }
        if attrs.by_key(&sym::fundamental).exists() {
            flags |= StructFlags::FUNDAMENTAL;
        }

        let repr = attrs.repr();

        let hir_expand::files::InFileWrapper { file_id, value } = loc.source(db);
        let (store, generic_params, source_map) = lower_generic_params(
            db,
            loc.container,
            id.into(),
            file_id,
            value.generic_param_list(),
            value.where_clause(),
        );
        (
            Arc::new(UnionSignature {
                generic_params,
                store,
                flags,
                repr,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }
}

bitflags! {
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct EnumFlags: u8 {
        const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS  = 1 << 1;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct EnumSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub flags: EnumFlags,
    pub repr: Option<ReprOptions>,
}

impl EnumSignature {
    pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);
        let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
        let mut flags = EnumFlags::empty();
        if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
            flags |= EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
        }

        let repr = attrs.repr();

        let hir_expand::files::InFileWrapper { file_id, value } = loc.source(db);
        let (store, generic_params, source_map) = lower_generic_params(
            db,
            loc.container,
            id.into(),
            file_id,
            value.generic_param_list(),
            value.where_clause(),
        );

        (
            Arc::new(EnumSignature {
                generic_params,
                store,
                flags,
                repr,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }

    pub fn variant_body_type(&self) -> IntegerType {
        match self.repr {
            Some(ReprOptions { int: Some(builtin), .. }) => builtin,
            _ => IntegerType::Pointer(true),
        }
    }
}
bitflags::bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct ConstFlags: u8 {
        const HAS_BODY = 1 << 1;
        const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 7;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct ConstSignature {
    pub name: Option<Name>,
    // generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub type_ref: TypeRefId,
    pub flags: ConstFlags,
}

impl ConstSignature {
    pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let module = loc.container.module(db);
        let attrs = item_tree.attrs(db, module.krate, ModItem::from(loc.id.value).into());
        let mut flags = ConstFlags::empty();
        if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
            flags |= ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL;
        }
        let source = loc.source(db);
        if source.value.body().is_some() {
            flags.insert(ConstFlags::HAS_BODY);
        }

        let (store, source_map, type_ref) =
            crate::expr_store::lower::lower_type_ref(db, module, source.map(|it| it.ty()));

        (
            Arc::new(ConstSignature {
                store: Arc::new(store),
                type_ref,
                flags,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }

    pub fn has_body(&self) -> bool {
        self.flags.contains(ConstFlags::HAS_BODY)
    }
}

bitflags::bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct StaticFlags: u8 {
        const HAS_BODY = 1 << 1;
        const MUTABLE    = 1 << 3;
        const UNSAFE     = 1 << 4;
        const EXPLICIT_SAFE = 1 << 5;
        const EXTERN     = 1 << 6;
        const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 7;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct StaticSignature {
    pub name: Name,

    // generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub type_ref: TypeRefId,
    pub flags: StaticFlags,
}
impl StaticSignature {
    pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let module = loc.container.module(db);
        let attrs = item_tree.attrs(db, module.krate, ModItem::from(loc.id.value).into());
        let mut flags = StaticFlags::empty();
        if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
            flags |= StaticFlags::RUSTC_ALLOW_INCOHERENT_IMPL;
        }

        if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
            flags.insert(StaticFlags::EXTERN);
        }

        let source = loc.source(db);
        if source.value.body().is_some() {
            flags.insert(StaticFlags::HAS_BODY);
        }
        if source.value.mut_token().is_some() {
            flags.insert(StaticFlags::MUTABLE);
        }
        if source.value.unsafe_token().is_some() {
            flags.insert(StaticFlags::UNSAFE);
        }
        if source.value.safe_token().is_some() {
            flags.insert(StaticFlags::EXPLICIT_SAFE);
        }

        let (store, source_map, type_ref) =
            crate::expr_store::lower::lower_type_ref(db, module, source.map(|it| it.ty()));

        (
            Arc::new(StaticSignature {
                store: Arc::new(store),
                type_ref,
                flags,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }
}

bitflags::bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct ImplFlags: u8 {
        const NEGATIVE = 1 << 1;
        const UNSAFE = 1 << 3;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct ImplSignature {
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub self_ty: TypeRefId,
    pub target_trait: Option<TraitRef>,
    pub flags: ImplFlags,
}

impl ImplSignature {
    pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);

        let mut flags = ImplFlags::empty();
        let src = loc.source(db);
        if src.value.unsafe_token().is_some() {
            flags.insert(ImplFlags::UNSAFE);
        }
        if src.value.excl_token().is_some() {
            flags.insert(ImplFlags::NEGATIVE);
        }

        let (store, source_map, self_ty, target_trait, generic_params) =
            crate::expr_store::lower::lower_impl(db, loc.container, src, id);

        (
            Arc::new(ImplSignature {
                store: Arc::new(store),
                generic_params,
                self_ty,
                target_trait,
                flags,
            }),
            Arc::new(source_map),
        )
    }
}

bitflags::bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct TraitFlags: u8 {
        const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1;
        const FUNDAMENTAL = 1 << 2;
        const UNSAFE = 1 << 3;
        const AUTO = 1 << 4;
        const SKIP_ARRAY_DURING_METHOD_DISPATCH = 1 << 5;
        const SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH = 1 << 6;
        const RUSTC_PAREN_SUGAR = 1 << 7;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct TraitSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub flags: TraitFlags,
}

impl TraitSignature {
    pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let mut flags = TraitFlags::empty();
        let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
        let source = loc.source(db);
        if source.value.auto_token().is_some() {
            flags.insert(TraitFlags::AUTO);
        }
        if source.value.unsafe_token().is_some() {
            flags.insert(TraitFlags::UNSAFE);
        }
        if attrs.by_key(&sym::fundamental).exists() {
            flags |= TraitFlags::FUNDAMENTAL;
        }
        if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
            flags |= TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
        }
        if attrs.by_key(&sym::rustc_paren_sugar).exists() {
            flags |= TraitFlags::RUSTC_PAREN_SUGAR;
        }
        let mut skip_array_during_method_dispatch =
            attrs.by_key(&sym::rustc_skip_array_during_method_dispatch).exists();
        let mut skip_boxed_slice_during_method_dispatch = false;
        for tt in attrs.by_key(&sym::rustc_skip_during_method_dispatch).tt_values() {
            for tt in tt.iter() {
                if let tt::iter::TtElement::Leaf(tt::Leaf::Ident(ident)) = tt {
                    skip_array_during_method_dispatch |= ident.sym == sym::array;
                    skip_boxed_slice_during_method_dispatch |= ident.sym == sym::boxed_slice;
                }
            }
        }

        if skip_array_during_method_dispatch {
            flags |= TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH;
        }
        if skip_boxed_slice_during_method_dispatch {
            flags |= TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH;
        }

        let (store, source_map, generic_params) = lower_trait(db, loc.container, source, id);

        (
            Arc::new(TraitSignature {
                store: Arc::new(store),
                generic_params,
                flags,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct TraitAliasSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
}

impl TraitAliasSignature {
    pub fn query(
        db: &dyn DefDatabase,
        id: TraitAliasId,
    ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let source = loc.source(db);
        let (store, source_map, generic_params) = lower_trait_alias(db, loc.container, source, id);

        (
            Arc::new(TraitAliasSignature {
                generic_params,
                store: Arc::new(store),
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }
}

bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct FnFlags: u16 {
        const HAS_BODY = 1 << 1;
        const DEFAULT = 1 << 2;
        const CONST = 1 << 3;
        const ASYNC = 1 << 4;
        const UNSAFE = 1 << 5;
        const HAS_VARARGS = 1 << 6;
        const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 7;
        const HAS_SELF_PARAM = 1 << 8;
        /// The `#[target_feature]` attribute is necessary to check safety (with RFC 2396),
        /// but keeping it for all functions will consume a lot of memory when there are
        /// only very few functions with it. So we only encode its existence here, and lookup
        /// it if needed.
        const HAS_TARGET_FEATURE = 1 << 9;
        const DEPRECATED_SAFE_2024 = 1 << 10;
        const EXPLICIT_SAFE = 1 << 11;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct FunctionSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub params: Box<[TypeRefId]>,
    pub ret_type: Option<TypeRefId>,
    pub abi: Option<Symbol>,
    pub flags: FnFlags,
    // FIXME: we should put this behind a fn flags + query to avoid bloating the struct
    pub legacy_const_generics_indices: Option<Box<Box<[u32]>>>,
}

impl FunctionSignature {
    pub fn query(
        db: &dyn DefDatabase,
        id: FunctionId,
    ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let module = loc.container.module(db);
        let item_tree = loc.id.item_tree(db);

        let mut flags = FnFlags::empty();
        let attrs = item_tree.attrs(db, module.krate, ModItem::from(loc.id.value).into());
        if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
            flags.insert(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL);
        }

        if attrs.by_key(&sym::target_feature).exists() {
            flags.insert(FnFlags::HAS_TARGET_FEATURE);
        }
        let legacy_const_generics_indices = attrs.rustc_legacy_const_generics();

        let source = loc.source(db);

        if source.value.unsafe_token().is_some() {
            if attrs.by_key(&sym::rustc_deprecated_safe_2024).exists() {
                flags.insert(FnFlags::DEPRECATED_SAFE_2024);
            } else {
                flags.insert(FnFlags::UNSAFE);
            }
        }
        if source.value.async_token().is_some() {
            flags.insert(FnFlags::ASYNC);
        }
        if source.value.const_token().is_some() {
            flags.insert(FnFlags::CONST);
        }
        if source.value.default_token().is_some() {
            flags.insert(FnFlags::DEFAULT);
        }
        if source.value.safe_token().is_some() {
            flags.insert(FnFlags::EXPLICIT_SAFE);
        }
        if source.value.body().is_some() {
            flags.insert(FnFlags::HAS_BODY);
        }

        let abi = source.value.abi().map(|abi| {
            abi.abi_string()
                .map_or_else(|| sym::C.clone(), |it| Symbol::intern(it.text_without_quotes()))
        });
        let (store, source_map, generic_params, params, ret_type, self_param, variadic) =
            lower_function(db, module, source, id);
        if self_param {
            flags.insert(FnFlags::HAS_SELF_PARAM);
        }
        if variadic {
            flags.insert(FnFlags::HAS_VARARGS);
        }
        (
            Arc::new(FunctionSignature {
                generic_params,
                store: Arc::new(store),
                params,
                ret_type,
                abi,
                flags,
                legacy_const_generics_indices,
                name: item_tree[loc.id.value].name.clone(),
            }),
            Arc::new(source_map),
        )
    }

    pub fn has_body(&self) -> bool {
        self.flags.contains(FnFlags::HAS_BODY)
    }

    /// True if the first param is `self`. This is relevant to decide whether this
    /// can be called as a method.
    pub fn has_self_param(&self) -> bool {
        self.flags.contains(FnFlags::HAS_SELF_PARAM)
    }

    pub fn is_default(&self) -> bool {
        self.flags.contains(FnFlags::DEFAULT)
    }

    pub fn is_const(&self) -> bool {
        self.flags.contains(FnFlags::CONST)
    }

    pub fn is_async(&self) -> bool {
        self.flags.contains(FnFlags::ASYNC)
    }

    pub fn is_unsafe(&self) -> bool {
        self.flags.contains(FnFlags::UNSAFE)
    }

    pub fn is_deprecated_safe_2024(&self) -> bool {
        self.flags.contains(FnFlags::DEPRECATED_SAFE_2024)
    }

    pub fn is_safe(&self) -> bool {
        self.flags.contains(FnFlags::EXPLICIT_SAFE)
    }

    pub fn is_varargs(&self) -> bool {
        self.flags.contains(FnFlags::HAS_VARARGS)
    }

    pub fn has_target_feature(&self) -> bool {
        self.flags.contains(FnFlags::HAS_TARGET_FEATURE)
    }
}

bitflags! {
    #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
    pub struct TypeAliasFlags: u8 {
        const RUSTC_HAS_INCOHERENT_INHERENT_IMPL = 1 << 1;
        const IS_EXTERN = 1 << 6;
        const RUSTC_ALLOW_INCOHERENT_IMPL = 1 << 7;
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct TypeAliasSignature {
    pub name: Name,
    pub generic_params: Arc<GenericParams>,
    pub store: Arc<ExpressionStore>,
    pub bounds: Box<[TypeBound]>,
    pub ty: Option<TypeRefId>,
    pub flags: TypeAliasFlags,
}

impl TypeAliasSignature {
    pub fn query(
        db: &dyn DefDatabase,
        id: TypeAliasId,
    ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let loc = id.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let mut flags = TypeAliasFlags::empty();
        let attrs = item_tree.attrs(
            db,
            loc.container.module(db).krate(),
            ModItem::from(loc.id.value).into(),
        );
        if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
            flags.insert(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPL);
        }
        if attrs.by_key(&sym::rustc_allow_incoherent_impl).exists() {
            flags.insert(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL);
        }
        if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
            flags.insert(TypeAliasFlags::IS_EXTERN);
        }
        let source = loc.source(db);
        let (store, source_map, generic_params, bounds, ty) =
            lower_type_alias(db, loc.container.module(db), source, id);

        (
            Arc::new(TypeAliasSignature {
                store: Arc::new(store),
                generic_params,
                flags,
                bounds,
                name: item_tree[loc.id.value].name.clone(),
                ty,
            }),
            Arc::new(source_map),
        )
    }
}

#[derive(Debug, PartialEq, Eq)]
pub struct FunctionBody {
    pub store: Arc<ExpressionStore>,
    pub parameters: Box<[PatId]>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct SimpleBody {
    pub store: Arc<ExpressionStore>,
}
pub type StaticBody = SimpleBody;
pub type ConstBody = SimpleBody;
pub type EnumVariantBody = SimpleBody;

#[derive(Debug, PartialEq, Eq)]
pub struct VariantFieldsBody {
    pub store: Arc<ExpressionStore>,
    pub fields: Box<[Option<ExprId>]>,
}

/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FieldData {
    pub name: Name,
    pub type_ref: TypeRefId,
    pub visibility: RawVisibility,
    pub is_unsafe: bool,
}

pub type LocalFieldId = Idx<FieldData>;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantFields {
    fields: Arena<FieldData>,
    pub store: Arc<ExpressionStore>,
    pub shape: FieldsShape,
}
impl VariantFields {
    #[inline]
    pub(crate) fn query(
        db: &dyn DefDatabase,
        id: VariantId,
    ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
        let (shape, (fields, store, source_map)) = match id {
            VariantId::EnumVariantId(id) => {
                let loc = id.lookup(db);
                let item_tree = loc.id.item_tree(db);
                let parent = loc.parent.lookup(db);
                let variant = &item_tree[loc.id.value];
                (
                    variant.shape,
                    lower_fields(
                        db,
                        parent.container,
                        &item_tree,
                        FieldParent::EnumVariant(loc.id.value),
                        loc.source(db).map(|src| {
                            variant.fields.iter().zip(
                                src.field_list()
                                    .map(|it| {
                                        match it {
                                            ast::FieldList::RecordFieldList(record_field_list) => {
                                                Either::Left(record_field_list.fields().map(|it| {
                                                    (SyntaxNodePtr::new(it.syntax()), it.ty())
                                                }))
                                            }
                                            ast::FieldList::TupleFieldList(field_list) => {
                                                Either::Right(field_list.fields().map(|it| {
                                                    (SyntaxNodePtr::new(it.syntax()), it.ty())
                                                }))
                                            }
                                        }
                                        .into_iter()
                                    })
                                    .into_iter()
                                    .flatten(),
                            )
                        }),
                        Some(item_tree[parent.id.value].visibility),
                    ),
                )
            }
            VariantId::StructId(id) => {
                let loc = id.lookup(db);
                let item_tree = loc.id.item_tree(db);
                let strukt = &item_tree[loc.id.value];
                (
                    strukt.shape,
                    lower_fields(
                        db,
                        loc.container,
                        &item_tree,
                        FieldParent::Struct(loc.id.value),
                        loc.source(db).map(|src| {
                            strukt.fields.iter().zip(
                                src.field_list()
                                    .map(|it| {
                                        match it {
                                            ast::FieldList::RecordFieldList(record_field_list) => {
                                                Either::Left(record_field_list.fields().map(|it| {
                                                    (SyntaxNodePtr::new(it.syntax()), it.ty())
                                                }))
                                            }
                                            ast::FieldList::TupleFieldList(field_list) => {
                                                Either::Right(field_list.fields().map(|it| {
                                                    (SyntaxNodePtr::new(it.syntax()), it.ty())
                                                }))
                                            }
                                        }
                                        .into_iter()
                                    })
                                    .into_iter()
                                    .flatten(),
                            )
                        }),
                        None,
                    ),
                )
            }
            VariantId::UnionId(id) => {
                let loc = id.lookup(db);
                let item_tree = loc.id.item_tree(db);
                let union = &item_tree[loc.id.value];
                (
                    FieldsShape::Record,
                    lower_fields(
                        db,
                        loc.container,
                        &item_tree,
                        FieldParent::Union(loc.id.value),
                        loc.source(db).map(|src| {
                            union.fields.iter().zip(
                                src.record_field_list()
                                    .map(|it| {
                                        it.fields()
                                            .map(|it| (SyntaxNodePtr::new(it.syntax()), it.ty()))
                                    })
                                    .into_iter()
                                    .flatten(),
                            )
                        }),
                        None,
                    ),
                )
            }
        };

        (Arc::new(VariantFields { fields, store: Arc::new(store), shape }), Arc::new(source_map))
    }

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

    pub fn fields(&self) -> &Arena<FieldData> {
        &self.fields
    }

    pub fn field(&self, name: &Name) -> Option<LocalFieldId> {
        self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
    }
}

fn lower_fields<'a>(
    db: &dyn DefDatabase,
    module: ModuleId,
    item_tree: &ItemTree,
    parent: FieldParent,
    fields: InFile<impl Iterator<Item = (&'a Field, (SyntaxNodePtr, Option<ast::Type>))>>,
    override_visibility: Option<RawVisibilityId>,
) -> (Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap) {
    let mut arena = Arena::new();
    let cfg_options = module.krate.cfg_options(db);
    let mut col = ExprCollector::new(db, module, fields.file_id);
    for (idx, (field, (ptr, ty))) in fields.value.enumerate() {
        let attr_owner = AttrOwner::make_field_indexed(parent, idx);
        let attrs = item_tree.attrs(db, module.krate, attr_owner);
        if attrs.is_cfg_enabled(cfg_options) {
            arena.alloc(FieldData {
                name: field.name.clone(),
                type_ref: col.lower_type_ref_opt(ty, &mut |_| TypeRef::Error),
                visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
                is_unsafe: field.is_unsafe,
            });
        } else {
            col.source_map.diagnostics.push(
                crate::expr_store::ExpressionStoreDiagnostics::InactiveCode {
                    node: InFile::new(fields.file_id, ptr),
                    cfg: attrs.cfg().unwrap(),
                    opts: cfg_options.clone(),
                },
            );
        }
    }
    let store = col.store.finish();
    (arena, store, col.source_map)
}

#[derive(Debug, PartialEq, Eq)]
pub struct InactiveEnumVariantCode {
    pub cfg: CfgExpr,
    pub opts: CfgOptions,
    pub ast_id: span::FileAstId<ast::Variant>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumVariants {
    pub variants: Box<[(EnumVariantId, Name)]>,
}

impl EnumVariants {
    pub(crate) fn enum_variants_query(
        db: &dyn DefDatabase,
        e: EnumId,
    ) -> (Arc<EnumVariants>, Option<Arc<ThinVec<InactiveEnumVariantCode>>>) {
        let loc = e.lookup(db);
        let item_tree = loc.id.item_tree(db);

        let mut diagnostics = ThinVec::new();
        let cfg_options = loc.container.krate.cfg_options(db);
        let mut index = 0;
        let variants = FileItemTreeId::range_iter(item_tree[loc.id.value].variants.clone())
            .filter_map(|variant| {
                let attrs = item_tree.attrs(db, loc.container.krate, variant.into());
                if attrs.is_cfg_enabled(cfg_options) {
                    let enum_variant = EnumVariantLoc {
                        id: ItemTreeId::new(loc.id.tree_id(), variant),
                        parent: e,
                        index,
                    }
                    .intern(db);
                    index += 1;
                    Some((enum_variant, item_tree[variant].name.clone()))
                } else {
                    diagnostics.push(InactiveEnumVariantCode {
                        ast_id: item_tree[variant].ast_id,
                        cfg: attrs.cfg().unwrap(),
                        opts: cfg_options.clone(),
                    });
                    None
                }
            })
            .collect();

        (
            Arc::new(EnumVariants { variants }),
            diagnostics.is_empty().not().then(|| Arc::new(diagnostics)),
        )
    }

    pub fn variant(&self, name: &Name) -> Option<EnumVariantId> {
        self.variants.iter().find_map(|(v, n)| if n == name { Some(*v) } else { None })
    }

    // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448)
    pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool {
        self.variants.iter().all(|&(v, _)| {
            // The condition check order is slightly modified from rustc
            // to improve performance by early returning with relatively fast checks
            let variant = &db.variant_fields(v.into());
            if !variant.fields().is_empty() {
                return false;
            }
            // The outer if condition is whether this variant has const ctor or not
            if !matches!(variant.shape, FieldsShape::Unit) {
                let body = db.body(v.into());
                // A variant with explicit discriminant
                if body.exprs[body.body_expr] != crate::hir::Expr::Missing {
                    return false;
                }
            }
            true
        })
    }
}
