//! Scalar bitsets.

use core::mem::size_of;
use core::ops::{Add, BitAnd, BitOr, Not, Shl, Shr, Sub};

/// A small bitset built on top of a single primitive integer type.
///
/// # Example
///
/// ```
/// use cranelift_bitset::ScalarBitSet;
///
/// // Create a new bitset backed with a `u32`.
/// let mut bitset = ScalarBitSet::<u32>::new();
///
/// // Bitsets are initially empty.
/// assert!(bitset.is_empty());
/// assert_eq!(bitset.len(), 0);
///
/// // Insert into the bitset.
/// bitset.insert(4);
/// bitset.insert(5);
/// bitset.insert(6);
///
/// // Now the bitset is not empty.
/// assert_eq!(bitset.len(), 3);
/// assert!(!bitset.is_empty());
/// assert!(bitset.contains(4));
/// assert!(bitset.contains(5));
/// assert!(bitset.contains(6));
///
/// // Remove an element from the bitset.
/// let was_present = bitset.remove(6);
/// assert!(was_present);
/// assert!(!bitset.contains(6));
/// assert_eq!(bitset.len(), 2);
///
/// // Can iterate over the elements in the set.
/// let elems: Vec<_> = bitset.iter().collect();
/// assert_eq!(elems, [4, 5]);
/// ```
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
    feature = "enable-serde",
    derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct ScalarBitSet<T>(pub T);

impl<T> core::fmt::Debug for ScalarBitSet<T>
where
    T: ScalarBitSetStorage,
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let mut s = f.debug_struct(core::any::type_name::<Self>());
        for i in 0..Self::capacity() {
            use alloc::string::ToString;
            let i = u8::try_from(i).unwrap();
            s.field(&i.to_string(), &self.contains(i));
        }
        s.finish()
    }
}

impl<T> Default for ScalarBitSet<T>
where
    T: ScalarBitSetStorage,
{
    #[inline]
    fn default() -> Self {
        Self::new()
    }
}

impl<T> ScalarBitSet<T>
where
    T: ScalarBitSetStorage,
{
    /// Create a new, empty bitset.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let bitset = ScalarBitSet::<u64>::new();
    ///
    /// assert!(bitset.is_empty());
    /// ```
    #[inline]
    pub fn new() -> Self {
        Self(T::from(0))
    }

    /// Construct a bitset with the half-open range `[lo, hi)` inserted.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let bitset = ScalarBitSet::<u64>::from_range(3, 6);
    ///
    /// assert_eq!(bitset.len(), 3);
    ///
    /// assert!(bitset.contains(3));
    /// assert!(bitset.contains(4));
    /// assert!(bitset.contains(5));
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `lo > hi` or if `hi > Self::capacity()`.
    ///
    /// ```should_panic
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// // The lower bound may not be larger than the upper bound.
    /// let bitset = ScalarBitSet::<u64>::from_range(6, 3);
    /// ```
    ///
    /// ```should_panic
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// // The bounds must fit within the backing scalar type.
    /// let bitset = ScalarBitSet::<u64>::from_range(3, 69);
    /// ```
    #[inline]
    pub fn from_range(lo: u8, hi: u8) -> Self {
        assert!(lo <= hi);
        assert!(hi <= Self::capacity());

        let one = T::from(1);

        // We can't just do (one << hi) - one here as the shift may overflow
        let hi_rng = if hi >= 1 {
            (one << (hi - 1)) + ((one << (hi - 1)) - one)
        } else {
            T::from(0)
        };

        let lo_rng = (one << lo) - one;

        Self(hi_rng - lo_rng)
    }

    /// The maximum number of bits that can be stored in this bitset.
    ///
    /// If you need more bits than this, use a
    /// [`CompoundBitSet`][crate::CompoundBitSet] instead of a `ScalarBitSet`.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// assert_eq!(ScalarBitSet::<u8>::capacity(), 8);
    /// assert_eq!(ScalarBitSet::<u64>::capacity(), 64);
    /// ```
    #[inline]
    pub fn capacity() -> u8 {
        u8::try_from(size_of::<T>()).unwrap() * 8
    }

    /// Get the number of elements in this set.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u64>::new();
    ///
    /// assert_eq!(bitset.len(), 0);
    ///
    /// bitset.insert(24);
    /// bitset.insert(13);
    /// bitset.insert(36);
    ///
    /// assert_eq!(bitset.len(), 3);
    /// ```
    #[inline]
    pub fn len(&self) -> u8 {
        self.0.count_ones()
    }

    /// Is this bitset empty?
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u16>::new();
    ///
    /// assert!(bitset.is_empty());
    ///
    /// bitset.insert(10);
    ///
    /// assert!(!bitset.is_empty());
    /// ```
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.0 == T::from(0)
    }

    /// Check whether this bitset contains `i`.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u8>::new();
    ///
    /// assert!(!bitset.contains(7));
    ///
    /// bitset.insert(7);
    ///
    /// assert!(bitset.contains(7));
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
    ///
    /// ```should_panic
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u8>::new();
    ///
    /// // A `ScalarBitSet<u8>` can only hold the elements `0..=7`, so `8` is
    /// // out of bounds and will trigger a panic.
    /// bitset.contains(8);
    /// ```
    #[inline]
    pub fn contains(&self, i: u8) -> bool {
        assert!(i < Self::capacity());
        self.0 & (T::from(1) << i) != T::from(0)
    }

    /// Insert `i` into this bitset.
    ///
    /// Returns whether the value was newly inserted. That is:
    ///
    /// * If the set did not previously contain `i` then `true` is returned.
    ///
    /// * If the set already contained `i` then `false` is returned.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u8>::new();
    ///
    /// // When an element is inserted that was not already present in the set,
    /// // then `true` is returned.
    /// let is_new = bitset.insert(7);
    /// assert!(is_new);
    ///
    /// // The element is now present in the set.
    /// assert!(bitset.contains(7));
    ///
    /// // And when the element is already in the set, `false` is returned from
    /// // `insert`.
    /// let is_new = bitset.insert(7);
    /// assert!(!is_new);
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
    ///
    /// ```should_panic
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u32>::new();
    ///
    /// // A `ScalarBitSet<u32>` can only hold the elements `0..=31`, so `42` is
    /// // out of bounds and will trigger a panic.
    /// bitset.insert(42);
    /// ```
    #[inline]
    pub fn insert(&mut self, i: u8) -> bool {
        let is_new = !self.contains(i);
        self.0 = self.0 | (T::from(1) << i);
        is_new
    }

    /// Remove `i` from this bitset.
    ///
    /// Returns whether `i` was previously in this set or not.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u128>::new();
    ///
    /// // Removing an element that was not present in the set returns `false`.
    /// let was_present = bitset.remove(100);
    /// assert!(!was_present);
    ///
    /// // And when the element was in the set, `true` is returned.
    /// bitset.insert(100);
    /// let was_present = bitset.remove(100);
    /// assert!(was_present);
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `i` is greater than or equal to [`Self::capacity()`][Self::capacity].
    ///
    /// ```should_panic
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u16>::new();
    ///
    /// // A `ScalarBitSet<u16>` can only hold the elements `0..=15`, so `20` is
    /// // out of bounds and will trigger a panic.
    /// bitset.remove(20);
    /// ```
    #[inline]
    pub fn remove(&mut self, i: u8) -> bool {
        let was_present = self.contains(i);
        self.0 = self.0 & !(T::from(1) << i);
        was_present
    }

    /// Remove all entries from this bitset.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u32>::new();
    ///
    /// bitset.insert(10);
    /// bitset.insert(20);
    /// bitset.insert(30);
    ///
    /// bitset.clear();
    ///
    /// assert!(bitset.is_empty());
    /// ```
    #[inline]
    pub fn clear(&mut self) {
        self.0 = T::from(0);
    }

    /// Remove and return the largest value in the bitset.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u64>::new();
    ///
    /// bitset.insert(0);
    /// bitset.insert(24);
    /// bitset.insert(13);
    /// bitset.insert(36);
    ///
    /// assert_eq!(bitset.pop(), Some(36));
    /// assert_eq!(bitset.pop(), Some(24));
    /// assert_eq!(bitset.pop(), Some(13));
    /// assert_eq!(bitset.pop(), Some(0));
    /// assert_eq!(bitset.pop(), None);
    /// ```
    #[inline]
    pub fn pop(&mut self) -> Option<u8> {
        let max = self.max()?;
        self.remove(max);
        Some(max)
    }

    /// Return the smallest number contained in this bitset or `None` if this
    /// bitset is empty.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u64>::new();
    ///
    /// // When the bitset is empty, `min` returns `None`.
    /// assert_eq!(bitset.min(), None);
    ///
    /// bitset.insert(28);
    /// bitset.insert(1);
    /// bitset.insert(63);
    ///
    /// // When the bitset is not empty, it returns the smallest element.
    /// assert_eq!(bitset.min(), Some(1));
    /// ```
    #[inline]
    pub fn min(&self) -> Option<u8> {
        if self.0 == T::from(0) {
            None
        } else {
            Some(self.0.trailing_zeros())
        }
    }

    /// Return the largest number contained in the bitset or None if this bitset
    /// is empty
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u64>::new();
    ///
    /// // When the bitset is empty, `max` returns `None`.
    /// assert_eq!(bitset.max(), None);
    ///
    /// bitset.insert(0);
    /// bitset.insert(36);
    /// bitset.insert(49);
    ///
    /// // When the bitset is not empty, it returns the smallest element.
    /// assert_eq!(bitset.max(), Some(49));
    /// ```
    #[inline]
    pub fn max(&self) -> Option<u8> {
        if self.0 == T::from(0) {
            None
        } else {
            let leading_zeroes = self.0.leading_zeros();
            Some(Self::capacity() - leading_zeroes - 1)
        }
    }

    /// Iterate over the items in this set.
    ///
    /// Items are always yielded in sorted order.
    ///
    /// # Example
    ///
    /// ```
    /// use cranelift_bitset::ScalarBitSet;
    ///
    /// let mut bitset = ScalarBitSet::<u64>::new();
    ///
    /// bitset.insert(19);
    /// bitset.insert(3);
    /// bitset.insert(63);
    /// bitset.insert(0);
    ///
    /// assert_eq!(
    ///     bitset.iter().collect::<Vec<_>>(),
    ///     [0, 3, 19, 63],
    /// );
    /// ```
    #[inline]
    pub fn iter(&self) -> Iter<T> {
        Iter {
            value: self.0,
            index: 0,
        }
    }
}

impl<T> IntoIterator for ScalarBitSet<T>
where
    T: ScalarBitSetStorage,
{
    type Item = u8;

    type IntoIter = Iter<T>;

    #[inline]
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, T> IntoIterator for &'a ScalarBitSet<T>
where
    T: ScalarBitSetStorage,
{
    type Item = u8;

    type IntoIter = Iter<T>;

    #[inline]
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

/// A trait implemented by all integers that can be used as the backing storage
/// for a [`ScalarBitSet`].
///
/// You shouldn't have to implement this yourself, it is already implemented for
/// `u{8,16,32,64,128}` and if you need more bits than that, then use
/// [`CompoundBitSet`][crate::CompoundBitSet] instead.
pub trait ScalarBitSetStorage:
    Default
    + From<u8>
    + Shl<u8, Output = Self>
    + Shr<u8, Output = Self>
    + BitAnd<Output = Self>
    + BitOr<Output = Self>
    + Not<Output = Self>
    + Sub<Output = Self>
    + Add<Output = Self>
    + PartialEq
    + Copy
{
    /// Count the number of leading zeros.
    fn leading_zeros(self) -> u8;

    /// Count the number of trailing zeros.
    fn trailing_zeros(self) -> u8;

    /// Count the number of bits set in this integer.
    fn count_ones(self) -> u8;
}

macro_rules! impl_storage {
    ( $int:ty ) => {
        impl ScalarBitSetStorage for $int {
            fn leading_zeros(self) -> u8 {
                u8::try_from(self.leading_zeros()).unwrap()
            }

            fn trailing_zeros(self) -> u8 {
                u8::try_from(self.trailing_zeros()).unwrap()
            }

            fn count_ones(self) -> u8 {
                u8::try_from(self.count_ones()).unwrap()
            }
        }
    };
}

impl_storage!(u8);
impl_storage!(u16);
impl_storage!(u32);
impl_storage!(u64);
impl_storage!(u128);
impl_storage!(usize);

/// An iterator over the elements in a [`ScalarBitSet`].
pub struct Iter<T> {
    value: T,
    index: u8,
}

impl<T> Iterator for Iter<T>
where
    T: ScalarBitSetStorage,
{
    type Item = u8;

    #[inline]
    fn next(&mut self) -> Option<u8> {
        if self.value == T::from(0) {
            None
        } else {
            let trailing_zeros = self.value.trailing_zeros();
            let elem = self.index + trailing_zeros;
            self.index += trailing_zeros + 1;
            self.value = self.value >> (trailing_zeros + 1);
            Some(elem)
        }
    }
}
