//! Detecting whether a type is infinitely-sized.

use hir_def::{AdtId, VariantId, hir::generics::GenericParams};
use rustc_type_ir::inherent::IntoKind;

use crate::{
    db::HirDatabase,
    next_solver::{GenericArgKind, GenericArgs, Ty, TyKind},
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Representability {
    Representable,
    Infinite,
}

macro_rules! rtry {
    ($e:expr) => {
        match $e {
            e @ Representability::Infinite => return e,
            Representability::Representable => {}
        }
    };
}

#[salsa::tracked(cycle_result = representability_cycle, returns(copy))]
pub(crate) fn representability(db: &dyn HirDatabase, id: AdtId) -> Representability {
    match id {
        AdtId::StructId(id) => variant_representability(db, id.into()),
        AdtId::UnionId(id) => variant_representability(db, id.into()),
        AdtId::EnumId(id) => {
            for &(variant, ..) in id.enum_variants(db).variants.values() {
                rtry!(variant_representability(db, variant.into()));
            }
            Representability::Representable
        }
    }
}

pub(crate) fn representability_cycle(
    _db: &dyn HirDatabase,
    _: salsa::Id,
    _id: AdtId,
) -> Representability {
    Representability::Infinite
}

fn variant_representability(db: &dyn HirDatabase, id: VariantId) -> Representability {
    for ty in db.field_types(id).values() {
        rtry!(representability_ty(db, ty.ty().instantiate_identity().skip_norm_wip()));
    }
    Representability::Representable
}

fn representability_ty<'db>(db: &'db dyn HirDatabase, ty: Ty<'db>) -> Representability {
    match ty.kind() {
        TyKind::Adt(adt_id, args) => representability_adt_ty(db, adt_id.def_id(), args),
        // FIXME(#11924) allow zero-length arrays?
        TyKind::Array(ty, _) => representability_ty(db, ty),
        TyKind::Tuple(tys) => {
            for ty in tys {
                rtry!(representability_ty(db, ty));
            }
            Representability::Representable
        }
        _ => Representability::Representable,
    }
}

fn representability_adt_ty<'db>(
    db: &'db dyn HirDatabase,
    def_id: AdtId,
    args: GenericArgs<'db>,
) -> Representability {
    rtry!(representability(db, def_id));

    // At this point, we know that the item of the ADT type is representable;
    // but the type parameters may cause a cycle with an upstream type
    let params_in_repr = params_in_repr(db, def_id);
    for (i, arg) in args.iter().enumerate() {
        if let GenericArgKind::Type(ty) = arg.kind()
            && params_in_repr[i]
        {
            rtry!(representability_ty(db, ty));
        }
    }
    Representability::Representable
}

fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> {
    let generics = GenericParams::of(db, def_id.into());
    let mut params_in_repr = (0..generics.len_lifetimes() + generics.len_type_or_consts())
        .map(|_| false)
        .collect::<Box<[bool]>>();
    let mut handle_variant = |variant| {
        for field in db.field_types(variant).values() {
            params_in_repr_ty(
                db,
                field.ty().instantiate_identity().skip_norm_wip(),
                &mut params_in_repr,
            );
        }
    };
    match def_id {
        AdtId::StructId(def_id) => handle_variant(def_id.into()),
        AdtId::UnionId(def_id) => handle_variant(def_id.into()),
        AdtId::EnumId(def_id) => {
            for &(variant, ..) in def_id.enum_variants(db).variants.values() {
                handle_variant(variant.into());
            }
        }
    }
    params_in_repr
}

fn params_in_repr_ty<'db>(db: &'db dyn HirDatabase, ty: Ty<'db>, params_in_repr: &mut [bool]) {
    match ty.kind() {
        TyKind::Adt(adt, args) => {
            let inner_params_in_repr = self::params_in_repr(db, adt.def_id());
            for (i, arg) in args.iter().enumerate() {
                if let GenericArgKind::Type(ty) = arg.kind()
                    && inner_params_in_repr[i]
                {
                    params_in_repr_ty(db, ty, params_in_repr);
                }
            }
        }
        TyKind::Array(ty, _) => params_in_repr_ty(db, ty, params_in_repr),
        TyKind::Tuple(tys) => tys.iter().for_each(|ty| params_in_repr_ty(db, ty, params_in_repr)),
        TyKind::Param(param) => {
            params_in_repr[param.index as usize] = true;
        }
        _ => {}
    }
}
