"""List CDT operation helpers.

Each function returns an operation dict for use with ``client.operate()``
and ``client.operate_ordered()``.
"""

from typing import Any, Optional

from aerospike_py._types import _UNSET, ListPolicy, Operation, _build_op

__all__ = [
    "Operation",
    "list_append",
    "list_append_items",
    "list_insert",
    "list_insert_items",
    "list_pop",
    "list_pop_range",
    "list_remove",
    "list_remove_range",
    "list_set",
    "list_trim",
    "list_clear",
    "list_size",
    "list_get",
    "list_get_range",
    "list_get_by_value",
    "list_get_by_index",
    "list_get_by_index_range",
    "list_get_by_rank",
    "list_get_by_rank_range",
    "list_get_by_value_list",
    "list_get_by_value_range",
    "list_remove_by_value",
    "list_remove_by_value_list",
    "list_remove_by_value_range",
    "list_remove_by_index",
    "list_remove_by_index_range",
    "list_remove_by_rank",
    "list_remove_by_rank_range",
    "list_increment",
    "list_sort",
    "list_set_order",
]

# List operation codes (must match rust/src/operations.rs CDT codes)
_OP_LIST_APPEND = 1001
_OP_LIST_APPEND_ITEMS = 1002
_OP_LIST_INSERT = 1003
_OP_LIST_INSERT_ITEMS = 1004
_OP_LIST_POP = 1005
_OP_LIST_POP_RANGE = 1006
_OP_LIST_REMOVE = 1007
_OP_LIST_REMOVE_RANGE = 1008
_OP_LIST_SET = 1009
_OP_LIST_TRIM = 1010
_OP_LIST_CLEAR = 1011
_OP_LIST_SIZE = 1012
_OP_LIST_GET = 1013
_OP_LIST_GET_RANGE = 1014
_OP_LIST_GET_BY_VALUE = 1015
_OP_LIST_GET_BY_INDEX = 1016
_OP_LIST_GET_BY_INDEX_RANGE = 1017
_OP_LIST_GET_BY_RANK = 1018
_OP_LIST_GET_BY_RANK_RANGE = 1019
_OP_LIST_GET_BY_VALUE_LIST = 1020
_OP_LIST_GET_BY_VALUE_RANGE = 1021
_OP_LIST_REMOVE_BY_VALUE = 1022
_OP_LIST_REMOVE_BY_VALUE_LIST = 1023
_OP_LIST_REMOVE_BY_VALUE_RANGE = 1024
_OP_LIST_REMOVE_BY_INDEX = 1025
_OP_LIST_REMOVE_BY_INDEX_RANGE = 1026
_OP_LIST_REMOVE_BY_RANK = 1027
_OP_LIST_REMOVE_BY_RANK_RANGE = 1028
_OP_LIST_INCREMENT = 1029
_OP_LIST_SORT = 1030
_OP_LIST_SET_ORDER = 1031


def list_append(bin: str, val: Any, policy: Optional[ListPolicy] = None) -> Operation:
    """Append a value to a list bin."""
    return _build_op(_OP_LIST_APPEND, bin, val=val, list_policy=policy or _UNSET)


def list_append_items(bin: str, values: list[Any], policy: Optional[ListPolicy] = None) -> Operation:
    """Append multiple values to a list bin."""
    return _build_op(_OP_LIST_APPEND_ITEMS, bin, val=values, list_policy=policy or _UNSET)


def list_insert(bin: str, index: int, val: Any, policy: Optional[ListPolicy] = None) -> Operation:
    """Insert a value at the given index."""
    return _build_op(_OP_LIST_INSERT, bin, index=index, val=val, list_policy=policy or _UNSET)


def list_insert_items(bin: str, index: int, values: list[Any], policy: Optional[ListPolicy] = None) -> Operation:
    """Insert multiple values at the given index."""
    return _build_op(_OP_LIST_INSERT_ITEMS, bin, index=index, val=values, list_policy=policy or _UNSET)


def list_pop(bin: str, index: int) -> Operation:
    """Remove and return the item at the given index."""
    return _build_op(_OP_LIST_POP, bin, index=index)


def list_pop_range(bin: str, index: int, count: int) -> Operation:
    """Remove and return `count` items starting at `index`."""
    return _build_op(_OP_LIST_POP_RANGE, bin, index=index, count=count)


def list_remove(bin: str, index: int) -> Operation:
    """Remove the item at the given index."""
    return _build_op(_OP_LIST_REMOVE, bin, index=index)


def list_remove_range(bin: str, index: int, count: int) -> Operation:
    """Remove `count` items starting at `index`."""
    return _build_op(_OP_LIST_REMOVE_RANGE, bin, index=index, count=count)


def list_set(bin: str, index: int, val: Any) -> Operation:
    """Set the value at the given index."""
    return _build_op(_OP_LIST_SET, bin, index=index, val=val)


def list_trim(bin: str, index: int, count: int) -> Operation:
    """Remove items outside the specified range."""
    return _build_op(_OP_LIST_TRIM, bin, index=index, count=count)


def list_clear(bin: str) -> Operation:
    """Remove all items from a list bin."""
    return _build_op(_OP_LIST_CLEAR, bin)


def list_size(bin: str) -> Operation:
    """Return the number of items in a list bin."""
    return _build_op(_OP_LIST_SIZE, bin)


def list_get(bin: str, index: int) -> Operation:
    """Get the item at the given index."""
    return _build_op(_OP_LIST_GET, bin, index=index)


def list_get_range(bin: str, index: int, count: int) -> Operation:
    """Get `count` items starting at `index`."""
    return _build_op(_OP_LIST_GET_RANGE, bin, index=index, count=count)


def list_get_by_value(bin: str, val: Any, return_type: int) -> Operation:
    """Get items matching the given value."""
    return _build_op(_OP_LIST_GET_BY_VALUE, bin, val=val, return_type=return_type)


def list_get_by_index(bin: str, index: int, return_type: int) -> Operation:
    """Get item by index with the specified return type."""
    return _build_op(_OP_LIST_GET_BY_INDEX, bin, index=index, return_type=return_type)


def list_get_by_index_range(bin: str, index: int, return_type: int, count: Optional[int] = None) -> Operation:
    """Get items by index range with the specified return type."""
    return _build_op(
        _OP_LIST_GET_BY_INDEX_RANGE,
        bin,
        index=index,
        return_type=return_type,
        count=count if count is not None else _UNSET,
    )


def list_get_by_rank(bin: str, rank: int, return_type: int) -> Operation:
    """Get item by rank with the specified return type."""
    return _build_op(_OP_LIST_GET_BY_RANK, bin, rank=rank, return_type=return_type)


def list_get_by_rank_range(bin: str, rank: int, return_type: int, count: Optional[int] = None) -> Operation:
    """Get items by rank range with the specified return type."""
    return _build_op(
        _OP_LIST_GET_BY_RANK_RANGE,
        bin,
        rank=rank,
        return_type=return_type,
        count=count if count is not None else _UNSET,
    )


def list_get_by_value_list(bin: str, values: list[Any], return_type: int) -> Operation:
    """Get items matching any of the given values."""
    return _build_op(_OP_LIST_GET_BY_VALUE_LIST, bin, val=values, return_type=return_type)


def list_get_by_value_range(bin: str, begin: Any, end: Any, return_type: int) -> Operation:
    """Get items with values in the range [begin, end)."""
    return _build_op(_OP_LIST_GET_BY_VALUE_RANGE, bin, val=begin, val_end=end, return_type=return_type)


def list_remove_by_value(bin: str, val: Any, return_type: int) -> Operation:
    """Remove items matching the given value."""
    return _build_op(_OP_LIST_REMOVE_BY_VALUE, bin, val=val, return_type=return_type)


def list_remove_by_value_list(bin: str, values: list[Any], return_type: int) -> Operation:
    """Remove items matching any of the given values."""
    return _build_op(_OP_LIST_REMOVE_BY_VALUE_LIST, bin, val=values, return_type=return_type)


def list_remove_by_value_range(bin: str, begin: Any, end: Any, return_type: int) -> Operation:
    """Remove items with values in the range [begin, end)."""
    return _build_op(_OP_LIST_REMOVE_BY_VALUE_RANGE, bin, val=begin, val_end=end, return_type=return_type)


def list_remove_by_index(bin: str, index: int, return_type: int) -> Operation:
    """Remove item by index with the specified return type."""
    return _build_op(_OP_LIST_REMOVE_BY_INDEX, bin, index=index, return_type=return_type)


def list_remove_by_index_range(bin: str, index: int, return_type: int, count: Optional[int] = None) -> Operation:
    """Remove items by index range."""
    return _build_op(
        _OP_LIST_REMOVE_BY_INDEX_RANGE,
        bin,
        index=index,
        return_type=return_type,
        count=count if count is not None else _UNSET,
    )


def list_remove_by_rank(bin: str, rank: int, return_type: int) -> Operation:
    """Remove item by rank."""
    return _build_op(_OP_LIST_REMOVE_BY_RANK, bin, rank=rank, return_type=return_type)


def list_remove_by_rank_range(bin: str, rank: int, return_type: int, count: Optional[int] = None) -> Operation:
    """Remove items by rank range."""
    return _build_op(
        _OP_LIST_REMOVE_BY_RANK_RANGE,
        bin,
        rank=rank,
        return_type=return_type,
        count=count if count is not None else _UNSET,
    )


def list_increment(bin: str, index: int, val: int, policy: Optional[ListPolicy] = None) -> Operation:
    """Increment the value at the given index."""
    return _build_op(_OP_LIST_INCREMENT, bin, index=index, val=val, list_policy=policy or _UNSET)


def list_sort(bin: str, sort_flags: int = 0) -> Operation:
    """Sort the list."""
    return _build_op(_OP_LIST_SORT, bin, val=sort_flags)


def list_set_order(bin: str, list_order: int = 0) -> Operation:
    """Set the list order."""
    return _build_op(_OP_LIST_SET_ORDER, bin, val=list_order)
