import asyncio
import logging
import random


async def gestiona_cinta(
        reader: asyncio.StreamReader,
        writer: asyncio.StreamWriter
) -> None:
    try:
        while line := await reader.readline():
        # async for line in reader:
            writer.write(b"OK\n")
            await writer.drain()
    except Exception:
        logging.exception("Excepció en gestiona_cinta", exc_info=True)
    finally:
        writer.close()
        await writer.wait_closed()


async def gestiona_estat_cinta(
        estat_cintes,
        reader: asyncio.StreamReader,
        writer: asyncio.StreamWriter
) -> None:
    try:
        missatge = await reader.readline()
        id_cinta = extreu_id(missatge.decode())
        resposta = f"OK {id_cinta}\n"
        writer.write(resposta.encode())
        await writer.drain()
        while missatge := await reader.readline():
        # async for missatge in reader:
            estat = extreu_estat(missatge.decode())
            estat_cintes[id_cinta] = estat
            resposta = f"OK {estat}\n"
            writer.write(resposta.encode())
            await writer.drain()
    except Exception:
        logging.exception("Excepció en gestiona_estat_cinta", exc_info=True)
    finally:
        writer.close()
        await writer.wait_closed()


def extreu_id(missatge):
    tipus, id_cinta = missatge.split()
    assert tipus == 'ID', "Error de protocol"
    return id_cinta


def extreu_estat(missatge):
    parts = missatge.split()
    match parts:
        case ["VELOCITAT", v] if float(v) == 0:
            estat = "ATURADA"
        case ["VELOCITAT", v]:
            estat = "MOVIMENT"
        case ["AVARIA"]:
            estat = "AVARIADA"
        case _:
            assert False, f"Error de protocol {parts}"
    return estat


def genera_missatges(id_cinta):
    m = f"ID {id_cinta}"
    while True:
        yield m + '\n'
        r = random.random()
        if r < 0.1:
            m = 'AVARIA'
        elif r < 0.3:
            m = 'VELOCITAT 0'
        else:
            m = F'VELOCITAT {r*10:3.1f}'
        
