# -*- coding: utf-8 -*-
"""
范围分片

限制 SimpleSlice 的读取范围
"""

from typing import Optional
from .base import SimpleSlice


class RangeSlice(SimpleSlice):
    """
    范围分片
    
    包装一个 SimpleSlice，限制其读取范围。
    
    Attributes:
        inner: 内部分片对象
        start: 起始位置
        end: 结束位置（不包含）
    """
    
    def __init__(self, inner: SimpleSlice, start: int, end: int) -> None:
        """
        初始化范围分片
        
        Args:
            inner: 内部分片对象
            start: 起始位置
            end: 结束位置（不包含）
        
        Raises:
            ValueError: 范围无效
        """
        super().__init__()
        
        if start < 0:
            raise ValueError(f"起始位置不能为负数：{start}")
        if end > len(inner):
            raise ValueError(f"结束位置超出范围：{end} > {len(inner)}")
        if start >= end:
            raise ValueError(f"起始位置必须小于结束位置：{start} >= {end}")
        
        self._inner = inner
        self._start = start
        self._end = end
        self._length = end - start
        self._position = 0
    
    async def read_abstract(self, size: int = -1) -> bytes:
        """
        读取数据
        
        Args:
            size: 读取大小，-1 表示读取到结束
        
        Returns:
            bytes: 读取的数据
        """
        if self._position >= self._length:
            return b""
        
        remaining = self._length - self._position
        if size < 0 or size > remaining:
            size = remaining
        
        await self._inner.seek(self._start + self._position)
        data = await self._inner.read_abstract(size)
        self._position += len(data)
        
        return data
    
    async def seek(self, position: int) -> None:
        """
        定位到指定位置
        
        Args:
            position: 目标位置
        """
        if position < 0 or position > self._length:
            raise ValueError(f"无效的位置：{position}")
        self._position = position
    
    def __len__(self) -> int:
        """返回分片长度"""
        return self._length
    
    async def _close(self) -> None:
        """关闭分片"""
        await self._inner.close()
        self._inner = None
    
    @property
    def start(self) -> int:
        """起始位置"""
        return self._start
    
    @property
    def end(self) -> int:
        """结束位置"""
        return self._end