use std::fmt::{self, Debug};
use std::num::NonZero;
use std::ops::RangeInclusive;

use serde::Serialize;

use crate::compiler_interface::with;
use crate::mir::FieldIdx;
use crate::target::{MachineInfo, MachineSize as Size};
use crate::ty::{Align, Ty, VariantIdx};
use crate::{Error, Opaque, error};

/// A function ABI definition.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct FnAbi {
    /// The types of each argument.
    pub args: Vec<ArgAbi>,

    /// The expected return type.
    pub ret: ArgAbi,

    /// The count of non-variadic arguments.
    ///
    /// Should only be different from `args.len()` when a function is a C variadic function.
    pub fixed_count: u32,

    /// The ABI convention.
    pub conv: CallConvention,

    /// Whether this is a variadic C function,
    pub c_variadic: bool,
}

/// Information about the ABI of a function's argument, or return value.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct ArgAbi {
    pub ty: Ty,
    pub layout: Layout,
    pub mode: PassMode,
}

/// How a function argument should be passed in to the target function.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum PassMode {
    /// Ignore the argument.
    ///
    /// The argument is either uninhabited or a ZST.
    Ignore,
    /// Pass the argument directly.
    ///
    /// The argument has a layout abi of `Scalar` or `Vector`.
    Direct(Opaque),
    /// Pass a pair's elements directly in two arguments.
    ///
    /// The argument has a layout abi of `ScalarPair`.
    Pair(Opaque, Opaque),
    /// Pass the argument after casting it.
    Cast { pad_i32: bool, cast: Opaque },
    /// Pass the argument indirectly via a hidden pointer.
    Indirect { attrs: Opaque, meta_attrs: Opaque, on_stack: bool },
}

/// The layout of a type, alongside the type itself.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct TyAndLayout {
    pub ty: Ty,
    pub layout: Layout,
}

/// The layout of a type in memory.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct LayoutShape {
    /// The fields location within the layout
    pub fields: FieldsShape,

    /// Encodes information about multi-variant layouts.
    /// Even with `Multiple` variants, a layout still has its own fields! Those are then
    /// shared between all variants.
    ///
    /// To access all fields of this layout, both `fields` and the fields of the active variant
    /// must be taken into account.
    pub variants: VariantsShape,

    /// The `abi` defines how this data is passed between functions.
    pub abi: ValueAbi,

    /// The ABI mandated alignment in bytes.
    pub abi_align: Align,

    /// The size of this layout in bytes.
    pub size: Size,
}

impl LayoutShape {
    /// Returns `true` if the layout corresponds to an unsized type.
    #[inline]
    pub fn is_unsized(&self) -> bool {
        self.abi.is_unsized()
    }

    #[inline]
    pub fn is_sized(&self) -> bool {
        !self.abi.is_unsized()
    }

    /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
    pub fn is_1zst(&self) -> bool {
        self.is_sized() && self.size.bits() == 0 && self.abi_align == 1
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub struct Layout(usize);

impl Layout {
    pub fn shape(self) -> LayoutShape {
        with(|cx| cx.layout_shape(self))
    }
}

impl crate::IndexedVal for Layout {
    fn to_val(index: usize) -> Self {
        Layout(index)
    }
    fn to_index(&self) -> usize {
        self.0
    }
}

/// Describes how the fields of a type are shaped in memory.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum FieldsShape {
    /// Scalar primitives and `!`, which never have fields.
    Primitive,

    /// All fields start at no offset. The `usize` is the field count.
    Union(NonZero<usize>),

    /// Array/vector-like placement, with all fields of identical types.
    Array { stride: Size, count: u64 },

    /// Struct-like placement, with precomputed offsets.
    ///
    /// Fields are guaranteed to not overlap, but note that gaps
    /// before, between and after all the fields are NOT always
    /// padding, and as such their contents may not be discarded.
    /// For example, enum variants leave a gap at the start,
    /// where the discriminant field in the enum layout goes.
    Arbitrary {
        /// Offsets for the first byte of each field,
        /// ordered to match the source definition order.
        /// I.e.: It follows the same order as [super::ty::VariantDef::fields()].
        /// This vector does not go in increasing order.
        offsets: Vec<Size>,
    },
}

impl FieldsShape {
    pub fn fields_by_offset_order(&self) -> Vec<FieldIdx> {
        match self {
            FieldsShape::Primitive => vec![],
            FieldsShape::Union(_) | FieldsShape::Array { .. } => (0..self.count()).collect(),
            FieldsShape::Arbitrary { offsets, .. } => {
                let mut indices = (0..offsets.len()).collect::<Vec<_>>();
                indices.sort_by_key(|idx| offsets[*idx]);
                indices
            }
        }
    }

    pub fn count(&self) -> usize {
        match self {
            FieldsShape::Primitive => 0,
            FieldsShape::Union(count) => count.get(),
            FieldsShape::Array { count, .. } => *count as usize,
            FieldsShape::Arbitrary { offsets, .. } => offsets.len(),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum VariantsShape {
    /// A type with no valid variants. Must be uninhabited.
    Empty,

    /// Single enum variants, structs/tuples, unions, and all non-ADTs.
    Single { index: VariantIdx },

    /// Enum-likes with more than one inhabited variant: each variant comes with
    /// a *discriminant* (usually the same as the variant index but the user can
    /// assign explicit discriminant values). That discriminant is encoded
    /// as a *tag* on the machine. The layout of each variant is
    /// a struct, and they all have space reserved for the tag.
    /// For enums, the tag is the sole field of the layout.
    Multiple {
        tag: Scalar,
        tag_encoding: TagEncoding,
        tag_field: usize,
        variants: Vec<LayoutShape>,
    },
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum TagEncoding {
    /// The tag directly stores the discriminant, but possibly with a smaller layout
    /// (so converting the tag to the discriminant can require sign extension).
    Direct,

    /// Niche (values invalid for a type) encoding the discriminant:
    /// Discriminant and variant index coincide.
    /// The variant `untagged_variant` contains a niche at an arbitrary
    /// offset (field `tag_field` of the enum), which for a variant with
    /// discriminant `d` is set to
    /// `(d - niche_variants.start).wrapping_add(niche_start)`.
    ///
    /// For example, `Option<(usize, &T)>`  is represented such that
    /// `None` has a null pointer for the second tuple field, and
    /// `Some` is the identity function (with a non-null reference).
    Niche {
        untagged_variant: VariantIdx,
        niche_variants: RangeInclusive<VariantIdx>,
        niche_start: u128,
    },
}

/// Describes how values of the type are passed by target ABIs,
/// in terms of categories of C types there are ABI rules for.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum ValueAbi {
    Scalar(Scalar),
    ScalarPair(Scalar, Scalar),
    Vector {
        element: Scalar,
        count: u64,
    },
    Aggregate {
        /// If true, the size is exact, otherwise it's only a lower bound.
        sized: bool,
    },
}

impl ValueAbi {
    /// Returns `true` if the layout corresponds to an unsized type.
    pub fn is_unsized(&self) -> bool {
        match *self {
            ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false,
            ValueAbi::Aggregate { sized } => !sized,
        }
    }
}

/// Information about one scalar component of a Rust type.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)]
pub enum Scalar {
    Initialized {
        /// The primitive type used to represent this value.
        value: Primitive,
        /// The range that represents valid values.
        /// The range must be valid for the `primitive` size.
        valid_range: WrappingRange,
    },
    Union {
        /// Unions never have niches, so there is no `valid_range`.
        /// Even for unions, we need to use the correct registers for the kind of
        /// values inside the union, so we keep the `Primitive` type around.
        /// It is also used to compute the size of the scalar.
        value: Primitive,
    },
}

impl Scalar {
    pub fn has_niche(&self, target: &MachineInfo) -> bool {
        match self {
            Scalar::Initialized { value, valid_range } => {
                !valid_range.is_full(value.size(target)).unwrap()
            }
            Scalar::Union { .. } => false,
        }
    }
}

/// Fundamental unit of memory access and layout.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize)]
pub enum Primitive {
    /// The `bool` is the signedness of the `Integer` type.
    ///
    /// One would think we would not care about such details this low down,
    /// but some ABIs are described in terms of C types and ISAs where the
    /// integer arithmetic is done on {sign,zero}-extended registers, e.g.
    /// a negative integer passed by zero-extension will appear positive in
    /// the callee, and most operations on it will produce the wrong values.
    Int {
        length: IntegerLength,
        signed: bool,
    },
    Float {
        length: FloatLength,
    },
    Pointer(AddressSpace),
}

impl Primitive {
    pub fn size(self, target: &MachineInfo) -> Size {
        match self {
            Primitive::Int { length, .. } => Size::from_bits(length.bits()),
            Primitive::Float { length } => Size::from_bits(length.bits()),
            Primitive::Pointer(_) => target.pointer_width,
        }
    }
}

/// Enum representing the existing integer lengths.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub enum IntegerLength {
    I8,
    I16,
    I32,
    I64,
    I128,
}

/// Enum representing the existing float lengths.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub enum FloatLength {
    F16,
    F32,
    F64,
    F128,
}

impl IntegerLength {
    pub fn bits(self) -> usize {
        match self {
            IntegerLength::I8 => 8,
            IntegerLength::I16 => 16,
            IntegerLength::I32 => 32,
            IntegerLength::I64 => 64,
            IntegerLength::I128 => 128,
        }
    }
}

impl FloatLength {
    pub fn bits(self) -> usize {
        match self {
            FloatLength::F16 => 16,
            FloatLength::F32 => 32,
            FloatLength::F64 => 64,
            FloatLength::F128 => 128,
        }
    }
}

/// An identifier that specifies the address space that some operation
/// should operate on. Special address spaces have an effect on code generation,
/// depending on the target and the address spaces it implements.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct AddressSpace(pub u32);

impl AddressSpace {
    /// The default address space, corresponding to data space.
    pub const DATA: Self = AddressSpace(0);
}

/// Inclusive wrap-around range of valid values (bitwise representation), that is, if
/// start > end, it represents `start..=MAX`, followed by `0..=end`.
///
/// That is, for an i8 primitive, a range of `254..=2` means following
/// sequence:
///
///    254 (-2), 255 (-1), 0, 1, 2
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub struct WrappingRange {
    pub start: u128,
    pub end: u128,
}

impl WrappingRange {
    /// Returns `true` if `size` completely fills the range.
    #[inline]
    pub fn is_full(&self, size: Size) -> Result<bool, Error> {
        let Some(max_value) = size.unsigned_int_max() else {
            return Err(error!("Expected size <= 128 bits, but found {} instead", size.bits()));
        };
        if self.start <= max_value && self.end <= max_value {
            Ok(self.start == (self.end.wrapping_add(1) & max_value))
        } else {
            Err(error!("Range `{self:?}` out of bounds for size `{}` bits.", size.bits()))
        }
    }

    /// Returns `true` if `v` is contained in the range.
    #[inline(always)]
    pub fn contains(&self, v: u128) -> bool {
        if self.wraps_around() {
            self.start <= v || v <= self.end
        } else {
            self.start <= v && v <= self.end
        }
    }

    /// Returns `true` if the range wraps around.
    /// I.e., the range represents the union of `self.start..=MAX` and `0..=self.end`.
    /// Returns `false` if this is a non-wrapping range, i.e.: `self.start..=self.end`.
    #[inline]
    pub fn wraps_around(&self) -> bool {
        self.start > self.end
    }
}

impl Debug for WrappingRange {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.start > self.end {
            write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
        } else {
            write!(fmt, "{}..={}", self.start, self.end)?;
        }
        Ok(())
    }
}

/// General language calling conventions.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum CallConvention {
    C,
    Rust,

    Cold,
    PreserveMost,
    PreserveAll,

    Custom,

    // Target-specific calling conventions.
    ArmAapcs,
    CCmseNonSecureCall,
    CCmseNonSecureEntry,

    Msp430Intr,

    PtxKernel,

    GpuKernel,

    X86Fastcall,
    X86Intr,
    X86Stdcall,
    X86ThisCall,
    X86VectorCall,

    X86_64SysV,
    X86_64Win64,

    AvrInterrupt,
    AvrNonBlockingInterrupt,

    RiscvInterrupt,
}

#[non_exhaustive]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub struct ReprFlags {
    pub is_simd: bool,
    pub is_c: bool,
    pub is_transparent: bool,
    pub is_linear: bool,
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub enum IntegerType {
    /// Pointer-sized integer type, i.e. `isize` and `usize`.
    Pointer {
        /// Signedness. e.g. `true` for `isize`
        is_signed: bool,
    },
    /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`.
    Fixed {
        /// Length of this integer type. e.g. `IntegerLength::I8` for `u8`.
        length: IntegerLength,
        /// Signedness. e.g. `false` for `u8`
        is_signed: bool,
    },
}

/// Representation options provided by the user
#[non_exhaustive]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
pub struct ReprOptions {
    pub int: Option<IntegerType>,
    pub align: Option<Align>,
    pub pack: Option<Align>,
    pub flags: ReprFlags,
}
