import httpx
from urllib.parse import urljoin

from hermes_hls_security import validar_destino
from hermes_hls_fetch import MAX_SEGMENT

REDIRECTS = (301, 302, 303, 307, 308)


async def preparar_segmento(url):
    """
    Abre y valida el origen antes de devolver
    la respuesta HTTP al navegador.
    """
    cliente = httpx.AsyncClient(
        timeout=httpx.Timeout(20.0, connect=5.0),
        follow_redirects=False,
        trust_env=False
    )

    actual = validar_destino(url)

    try:
        for _ in range(4):
            validar_destino(actual)

            solicitud = cliente.build_request("GET", actual)
            respuesta = await cliente.send(
                solicitud,
                stream=True
            )

            if respuesta.status_code in REDIRECTS:
                destino = respuesta.headers.get("location")
                await respuesta.aclose()

                if not destino:
                    raise ValueError("Redireccion sin destino")

                actual = validar_destino(
                    urljoin(actual, destino)
                )
                continue

            try:
                respuesta.raise_for_status()

                longitud = respuesta.headers.get("content-length")

                if longitud and int(longitud) > MAX_SEGMENT:
                    raise ValueError("Segmento demasiado grande")

            except Exception:
                await respuesta.aclose()
                raise

            return cliente, respuesta

        raise ValueError("Demasiadas redirecciones")

    except BaseException:
        await cliente.aclose()
        raise


async def transmitir_preparado(cliente, respuesta):
    total = 0

    try:
        async for bloque in respuesta.aiter_bytes(65536):
            total += len(bloque)

            if total > MAX_SEGMENT:
                raise ValueError("Limite de segmento excedido")

            yield bloque

    finally:
        await respuesta.aclose()
        await cliente.aclose()
