//! The items structures.

use std::cmp::{Ord, PartialOrd};

use crate as androscalpel_serializer;
use crate::{EncodedArray, Serializable};

pub mod class;
pub mod code;
pub mod header;
pub mod hiddenapi;
pub mod instructions;
pub mod map;

pub use class::*;
pub use code::*;
pub use header::*;
pub use hiddenapi::*;
pub use instructions::*;
pub use map::*;

/// <https://source.android.com/docs/core/runtime/dex-format#string-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
pub struct StringIdItem {
    /// Offset of a [`crate::StringDataItem`].
    pub string_data_off: u32,
}

pub use crate::StringDataItem;

/// <https://source.android.com/docs/core/runtime/dex-format#type-id-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct TypeIdItem {
    /// Index of a [`StringIdItem`] in `string_ids`.
    pub descriptor_idx: u32,
}

/// <https://source.android.com/docs/core/runtime/dex-format#proto-id-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ProtoIdItem {
    /// Index of a [`StringIdItem`] in `string_ids`.
    pub shorty_idx: u32,
    /// Index of a [`TypeIdItem`] in `type_ids`.
    pub return_type_idx: u32,
    /// 0 if no parameter, else offset to a [`TypeList`].
    pub parameters_off: u32,
}

/// <https://source.android.com/docs/core/runtime/dex-format#field-id-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
pub struct FieldIdItem {
    /// Index of a [`TypeIdItem`] in `type_ids`, must be a class.
    pub class_idx: u16,
    /// Index of a [`TypeIdItem`] in `type_ids`.
    pub type_idx: u16,
    /// Index of a [`StringIdItem`] in `string_ids`.
    pub name_idx: u32,
}

/// <https://source.android.com/docs/core/runtime/dex-format#method-id-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MethodIdItem {
    /// Index of a [`TypeIdItem`] in `type_ids`, must be a class.
    pub class_idx: u16,
    /// Index of a [`ProtoIdItem`] in `proto_ids`.
    pub proto_idx: u16,
    /// Index of a [`StringIdItem`] in [`HeaderItem.string_ids`].
    pub name_idx: u32,
}

/// <https://source.android.com/docs/core/runtime/dex-format#call-site-id-item>
/// alignment: 4 bytes
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
pub struct CallSiteIdItem {
    /// Offset to a [`CallSiteItem`].
    pub call_site_off: u32,
}

/// <https://source.android.com/docs/core/runtime/dex-format#encoded-array-item>
/// alignment: none
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
pub struct EncodedArrayItem {
    pub value: EncodedArray,
}

/// <https://source.android.com/docs/core/runtime/dex-format#call-site-item>
///
/// The call_site_item is an encoded_array_item whose elements correspond to
/// the arguments provided to a bootstrap linker method.
///
/// The first three arguments are:
/// - A method handle representing the bootstrap linker method ([`crate::EncodedValue::MethodHandle`])
/// - A method name that the bootstrap linker should resolve ([`crate::EncodedValue::String`])
/// - A method type corresponding to the type of the method name to be resolved
///   ([`crate::EncodedValue::MethodType`])
///
/// Any additional arguments are constant values passed to the bootstrap linker method.
/// These arguments are passed in order and without any type conversions.
///
///
pub type CallSiteItem = EncodedArrayItem;
