use sp_arithmetic::traits::AtLeast8BitUnsigned;
use sp_runtime::traits::UniqueSaturatedInto;
use sp_std::vec::Vec;

pub trait BoundedBitmapMetadata {
    fn total_bits_capacity() -> u32;
    fn chunk_size() -> u32;
}

pub trait BoundedBitmapWriter {
    fn insert<N: Copy + TryInto<usize>>(&mut self, i: N) -> Option<N>;
    fn remove<N: Copy + TryInto<usize>>(&mut self, i: N) -> Option<N>;
    fn truncate(&mut self);
    fn nullify(&mut self);

}

pub trait BoundedBitmapReader {
    fn active_bits_count(&self) -> u32;
    fn highest_bit<N>(&self) -> Option<N>
    where
        usize: UniqueSaturatedInto<N>;
    fn count_ones<N>(&self) -> N
    where
        u32: UniqueSaturatedInto<N>;
    fn count_zeros<N>(&self) -> N
    where
        u32: UniqueSaturatedInto<N>;
    fn is_empty(&self) -> bool;
    fn contains<N>(&self, index: N) -> bool
    where
        N: UniqueSaturatedInto<usize>;
}

pub trait BoundedBitmapGenerator {
    fn empty<N>(n: N) -> Self
    where
        N: UniqueSaturatedInto<usize>;
    fn all_ones<N>(n: N) -> Self
    where
        N: UniqueSaturatedInto<usize>;
    fn empty_from(bitmap: &Self) -> Self;
    fn from_bitmask<Outer>(values: &Vec<Outer>) -> Self
    where
        Outer: AtLeast8BitUnsigned + num_traits::PrimInt;
    fn from_vec<Outer>(values: &Vec<Outer>) -> Self
    where
        Outer: AtLeast8BitUnsigned + TryInto<usize> + PartialEq + Copy;
}

pub trait BoundedBitmapIterable {
    type IntoIter<'a, ItemType>: Iterator<Item = ItemType> + 'a
    where
        Self: 'a,
        ItemType: 'static,
        u32: UniqueSaturatedInto<ItemType>;

    fn iter<ItemType>(&self) -> Self::IntoIter<'_, ItemType>
    where
        ItemType: 'static,
        u32: UniqueSaturatedInto<ItemType>;
}
