//! Bit-manipulation helpers, directly mapped from repeated WASM decompilation patterns.

/// 32-bit right rotate
#[inline(always)]
pub fn ror32(x: u32, n: u32) -> u32 {
    x.rotate_right(n)
}

/// 32-bit left rotate
#[inline(always)]
pub fn rol32(x: u32, n: u32) -> u32 {
    x.rotate_left(n)
}

/// 32-bit byte swap (endian conversion)
/// Decompiled pattern: x << 0x18 | (x & 0xff00) << 8 | x >> 8 & 0xff00 | x >> 0x18
#[inline(always)]
pub fn bswap32(x: u32) -> u32 {
    x.swap_bytes()
}

/// Full bit reversal: bswap → nibble_swap → bit_pair_swap → bit_swap
/// Used in inner_compress_gf2x4
#[inline]
pub fn bitrev32(x: u32) -> u32 {
    let x = bswap32(x);
    let x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
    let x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
    ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1)
}

/// Partial bit reversal (mask 0x55555554 instead of 0x55555555), then >> 1
/// Used in inner_compress_gf2x4
#[inline]
pub fn partial_bitrev_shr1(x: u32) -> u32 {
    let x = bswap32(x);
    let x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
    let x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
    (((x >> 1) & 0x55555554) | ((x & 0x55555555) << 1)) >> 1
}

/// Nibble half-swap (used in linear diffusion layers P1 and P2)
/// (x << 12 | x >> 20) & 0x0F0F0F0F | (x << 20 | x >> 12) & 0xF0F0F0F0
#[inline]
pub fn nibble_half_swap(x: u32) -> u32 {
    (x.rotate_left(12) & 0x0F0F0F0F) | (x.rotate_left(20) & 0xF0F0F0F0)
}
