use crate::{new_hash_type, new_key_type, new_vec_type, FixedVec};
use bounded_collections::ConstU32;
pub use config::*;

#[cfg(not(feature = "tiny"))]
mod config {
	/// Total number of validators.
	pub const VAL_COUNT: super::ValIndex = 1023;
	pub const CHUNK_POINTS: usize = 342;
	pub const CHUNKS_PER_SEGMENT: usize = 6;
}

#[cfg(feature = "tiny")]
mod config {
	/// Total number of validators.
	pub const VAL_COUNT: super::ValIndex = 6;
	pub const CHUNK_POINTS: usize = 2;
	pub const CHUNKS_PER_SEGMENT: usize = 32;
}

pub const POINT_LEN: usize = 2;
pub const SEGMENT_SLICE_LEN: usize = CHUNKS_PER_SEGMENT * POINT_LEN;
pub const CHUNK_LEN: usize = CHUNK_POINTS * POINT_LEN;
pub const SEGMENT_LEN: usize = CHUNK_LEN * CHUNKS_PER_SEGMENT;

/// Validators super-majority.
pub const VAL_SUPER_MAJORITY: u32 = VAL_COUNT as u32 / 3 * 2 + 1;

/// Maximum number of Work Items in a Work Package.
pub const MAX_WORK_ITEMS: u32 = 4;

/// Maximum number of imports in a Work Package.
pub const MAX_IMPORTS: u32 = 2048;

/// Maximum number of exports in a Work Package.
pub const MAX_EXPORTS: u32 = 2048;

/// Maximum number of dependencies (total of prerequisites and SR lookup entries).
pub const MAX_DEPENDENCIES: usize = 8;

pub const MAX_INPUT: u32 = 12 * 1024 * 1024;

/// Size of memo in transfers.
pub const MEMO_LEN: usize = 64;
/// Number of authorizations in allocation.
pub const AUTH_QUEUE_LEN: usize = 80;

/// Type that represents a time slot of 6 seconds, either in a relative sense or as a period which
/// has elapsed from the Polkadot Common Era (1200 UTC, 1 January 2024).
pub type Slot = u32;
/// Type to represent the index of a validator.
pub type ValIndex = u16;
/// Type to represent the index of a compute core.
pub type CoreIndex = u16;
/// Type to represent the index of a service.
pub type ServiceId = u32;
/// Type to represent a balance.
pub type Balance = u64;
/// Type which is double the length of Balance, for non-overflowing multiplies.
pub type DoubleBalance = u128;
/// Type to represent some gas.
pub type Gas = i64;
/// Type which is double the length of Gas, for non-overflowing multiplies.
pub type DoubleGas = u128;

pub type Hash = [u8; 32];

new_hash_type!(HeaderHash);
new_hash_type!(CodeHash);
new_hash_type!(WorkPackageHash);
new_hash_type!(WorkReportHash);
new_hash_type!(PayloadHash);
new_hash_type!(StateRootHash);
new_hash_type!(MmrPeakHash);
new_hash_type!(AccumulateRootHash);
new_hash_type!(ExtrinsicHash);
new_hash_type!(ItemHash);
new_hash_type!(AuthorizerHash);
new_hash_type!(SegmentTreeRoot);
new_hash_type!(SegmentHash);
new_hash_type!(MerkleNodeHash);
new_hash_type!(AnyHash);

new_vec_type!(Authorization);
new_vec_type!(Code);
new_vec_type!(WorkPayload);
new_vec_type!(AuthParam);
new_vec_type!(AnyVec);
// Output of `refine`.
new_vec_type!(WorkOutput);
// Output of `is_authorized`.
new_vec_type!(AuthOutput);
new_vec_type!(Bundle);

// A transaction memo.
new_key_type!(Memo, MEMO_LEN);
// Plain-old-data struct of the same length as `ed25519::Public`. No-cryptographic dependencies.
new_key_type!(OpaqueEd25519Public, 32);
// Plain-old-data struct of the same length as `bandersnatch::Public`. No-cryptographic
// dependencies.
new_key_type!(OpaqueBandersnatchPublic, 32);
// Some additional information on a validator.
new_key_type!(OpaqueValidatorMetadata, 64);

pub type AuthQueue = FixedVec<AuthorizerHash, ConstU32<{ AUTH_QUEUE_LEN as u32 }>>;

// TODO: Measure performance penalty for this not being 4096.
pub type Segment = FixedVec<u8, ConstU32<{ SEGMENT_LEN as u32 }>>;
