import numpy as np
import pytest

from amunpy.data_filters import filter_decode, shuffle_decode, bytedelta_decode, DataFilterError


def test_filter_decode_defaults_to_noop():
    b = bytes(range(64))
    assert filter_decode(b, data_encoder=None, dtype="int64") == b
    assert filter_decode(b, data_encoder="", dtype="int64") == b
    assert filter_decode(b, data_encoder="none", dtype="int64") == b
    assert filter_decode(b, data_encoder="  NONE  ", dtype="int64") == b


def test_filter_decode_unknown_encoder_raises():
    with pytest.raises(DataFilterError):
        filter_decode(b"\x00" * 16, data_encoder="unknown", dtype="int64")


def test_shuffle_decode_valid_length_is_divisible_by_itemsize():
    # dtype=int32 => itemsize=4; choose length divisible by 4
    b = bytes(range(64))
    out = shuffle_decode(b, dtype="int32")
    assert isinstance(out, (bytes, bytearray))
    assert len(out) == len(b)


def test_shuffle_decode_invalid_length_raises():
    # dtype=int64 => itemsize=8; length 9 should fail
    with pytest.raises(DataFilterError):
        shuffle_decode(b"\x00" * 9, dtype="int64")


def test_bytedelta_decode_valid_length_preserves_size():
    # dtype=int16 => itemsize=2; length divisible by 2
    b = bytes(range(64))
    out = bytedelta_decode(b, dtype="int16")
    assert isinstance(out, (bytes, bytearray))
    assert len(out) == len(b)


def test_bytedelta_decode_invalid_length_raises():
    with pytest.raises(DataFilterError):
        bytedelta_decode(b"\x00" * 7, dtype="int64")

def test_filter_decode_routes_to_shuffle():
    b = bytes(range(64))
    assert filter_decode(b, data_encoder="shuffle", dtype="int32") == shuffle_decode(b, dtype="int32")
