/*
 * Copyright 2026 Rive
 */

#ifndef _RIVE_BITWISE_HPP_
#define _RIVE_BITWISE_HPP_

#include <type_traits>

#include "rive/rive_types.hpp"
#include "rive/enums.hpp"
#include "rive/math/math_types.hpp"

namespace rive::math
{

// Attempt to generate a "clz" assembly instruction.
RIVE_ALWAYS_INLINE static int clz32(uint32_t x)
{
  assert(x != 0);
#if __has_builtin(__builtin_clz)
  return __builtin_clz(x);
#else
  uint64_t doubleBits = bit_cast<uint64_t>(static_cast<double>(x));
  return 1054 - (doubleBits >> 52);
#endif
}

RIVE_ALWAYS_INLINE static int clz64(uint64_t x)
{
  assert(x != 0);
#if __has_builtin(__builtin_clzll)
  return __builtin_clzll(x);
#else
  uint32_t hi32 = x >> 32;
  return hi32 != 0 ? clz32(hi32) : 32 + clz32(x & 0xffffffff);
#endif
}

// Returns the 1-based index of the most significat bit in x.
//
//   0    -> 0
//   1    -> 1
//   2..3 -> 2
//   4..7 -> 3
//   ...
//
RIVE_ALWAYS_INLINE static uint32_t msb(uint32_t x)
{
  return x != 0 ? 32 - clz32(x) : 0;
}

// Attempt to generate a "rotl" (rotate-left) assembly instruction.
RIVE_ALWAYS_INLINE static uint32_t rotateleft32(uint32_t x, int y)
{
#if __has_builtin(__builtin_rotateleft32)
  return __builtin_rotateleft32(x, y);
#else
  return (x << y) | (x >> (32 - y));
#endif
}

namespace internal
{
// For compilers where there isn't a built-in popcount function, here's the
// simplest efficient implementation. This is done here in a namespace so that
// it can be unit tested even on systems that have built-in popcount support.
template <typename I> constexpr uint32_t count_set_bits_fallback(I i) noexcept
{
  uint32_t count = 0;
  while (i != 0)
  {
    count++;

    // remove the lowest set bit from the given value
    i &= i - 1;
  }
  return count;
}

} // namespace internal

template <typename T> constexpr uint32_t count_set_bits(T i) noexcept
{
#if __has_builtin(__builtin_popcount)
  static_assert(std::is_integral_v<T>);
  if constexpr (sizeof(T) == sizeof(uint64_t))
  {
    return uint32_t(__builtin_popcountll(uint64_t(i)));
  }
  else
  {
    return uint32_t(__builtin_popcount(uint32_t(i)));
  }
#else
  return internal::count_set_bits_fallback(i);
#endif
}

// Give a value with bits set within a given mask, compact the bits down to the
// minimum number needed to represent the values that are set in the mask.
//  For example: a mask of 11010001 has 4 set bits, and so a value of 10x0xxx1
//   (where x is any bit value not within the mask) would be compacted to 1001
constexpr uint32_t compact_bitmask_value(uint32_t value, uint32_t mask) noexcept
{
  uint32_t compacted = 0;
  for (int32_t inBitIndex = 31; inBitIndex >= 0; inBitIndex--)
  {
    auto bit = 1u << inBitIndex;
    if ((mask & bit) != 0)
    {
      compacted <<= 1;
      compacted |= ((value & bit) != 0) ? 1 : 0;
    }
  }

  return compacted;
}

// Undo the operation that compactBitmaskValue does.
//  For example: a mask of 11010001, with a given compacted vaue of 1001 would
//  expand to 10000001 (where each 1 in "compacted" means setting the
//  corresponding bit from mask)
constexpr uint32_t expand_compacted_bitmask_value(
    uint32_t compacted,
    uint32_t mask) noexcept
{
  uint32_t expanded = 0;
  for (int32_t maskBitIndex = 0; maskBitIndex < 32; maskBitIndex++)
  {
    auto maskBit = 1u << maskBitIndex;
    if ((mask & maskBit) != 0)
    {
      if (compacted & 1)
      {
        expanded |= maskBit;
      }
      compacted >>= 1;
    }
  }

  return expanded;
}

// Iteratable returned from iterateBitCombinationsInMask
template <typename T> class BitCombinationIterable
{
public:
  explicit constexpr BitCombinationIterable(T mask) : m_mask(mask) {}

  class Iterator
  {
  public:
    explicit constexpr Iterator(T mask) noexcept
        : m_currentValue(mask)
        , m_mask(mask)
    {}

    constexpr static Iterator MakeEnd(T mask) noexcept
    {
      Iterator it{mask};
      it.m_wasAdvanced = true;
      return it;
    }

    constexpr Iterator& operator++() noexcept
    {
      m_wasAdvanced = true;

      // Do this operation as an unsigned integral version of the type.
      // For enums this allows the subtraction below to work, and for
      // signed integers this allows us to do wrapping subtraction
      // (subtracting from 0) without it being undefined behavior.
      // NOTE: The odd "enable_if" in there is a trick to delay evaluation
      // of underlying_type<T> until the conditional gets chosen, because
      // otherwise this won't compile for non-enum types
      using U = std::make_unsigned_t<typename std::conditional_t<
          std::is_enum_v<T>,
          std::underlying_type<T>,
          std::enable_if<true, T>>::type>;

      // We actually iterate through these combinations from most bits to
      // least bits because it's simpler. (Iterating forward can be
      // accomplished by starting at 0, and xoring with the mask before
      // and after this decrement, but it seemed unnecessary since it's
      // unlikely that the ordering matters anywhere)

      // This subtraction and mask effectively removes the lowest set bit
      // in the mask from the current value (and re-sets and mask bits
      // below it), that is with a mask of 01001010 and a current value of
      // 01001000, subtracting would give 01000111, then the mask leaves
      // it as 01000010, which is the next-lowest valid combination of
      // mask bits from where we were.
      m_currentValue = T(U(m_currentValue) - 1) & m_mask;

      return *this;
    }

    constexpr Iterator operator++(int) noexcept
    {
      auto prev = *this;
      ++(*this);
      return prev;
    }

    constexpr T operator*() const noexcept { return m_currentValue; }

    constexpr bool operator==(const Iterator& other) const noexcept
    {
      assert(m_mask == other.m_mask);
      return (
          m_currentValue == other.m_currentValue &&
          m_wasAdvanced == other.m_wasAdvanced);
    }

    constexpr bool operator!=(const Iterator& other) const noexcept
    {
      return !(*this == other);
    }

  private:
    T m_currentValue{};
    T m_mask{};
    bool m_wasAdvanced = false;
  };

  constexpr Iterator begin() const noexcept { return Iterator{m_mask}; }
  constexpr Iterator end() const noexcept { return Iterator::MakeEnd(m_mask); }

private:
  T m_mask;
};

// Iterate through all combinations of set/unset bits for a given mask.
// That is, for a mask that is 101011, it would iterate through:
// 101011, 101010, 101001, 101000, 100011, ...,  000001, 000000
template <typename T>
BitCombinationIterable<T> iterate_bit_combinations_in_mask(T mask)
{
  return BitCombinationIterable{mask};
}

// Shift bits into the bottom of a key value (ensuring that the key value does
// not overflow and the value fits within the specified bit count)
template <typename Key, typename Bits>
[[nodiscard]] Key add_bits_to_key(
    Key key,
    Bits bits,
    uint32_t bitCount) noexcept
{
  static_assert(sizeof(Bits) <= sizeof(Key));

  assert((key << bitCount) >> bitCount == key);
  assert((Key(bits) & ((1ull << bitCount) - 1)) == Key(bits));
  return (key << bitCount) | Key(bits);
}

} // namespace rive::math
#endif
