"""
Fetch GTFS realtime data from ZET.

https://www.zet.hr/odredbe/datoteke-u-gtfs-formatu/669
"""

import logging
from dataclasses import dataclass
from datetime import datetime
from typing import Generator

from aiohttp import ClientSession
from google.transit import gtfs_realtime_pb2

from zet.http import logger_trace_config


logger = logging.getLogger(__name__)


@dataclass
class VehiclePosition:
    trip_id: str
    route_id: str
    vehicle_id: str
    latitude: float
    longitude: float
    timestamp: datetime


async def get_vehicle_positions() -> list[VehiclePosition]:
    """Returns realtime vehicle positions"""
    try:
        logger.debug("Loading vehicle positions...")
        data = await fetch_realtime_data()
        positions = list(parse_realtime_data(data))
        logger.info(f"Loaded {len(positions)} vehicle positions")
        return positions
    except Exception:
        logger.exception("Failed loading vehicle positions")
        return []


def parse_realtime_data(data: bytes) -> Generator[VehiclePosition]:
    feed = gtfs_realtime_pb2.FeedMessage()  # type: ignore
    feed.ParseFromString(data)
    for entity in feed.entity:
        if entity.HasField("vehicle"):
            yield VehiclePosition(
                trip_id=entity.vehicle.trip.trip_id,
                route_id=entity.vehicle.trip.route_id,
                vehicle_id=entity.vehicle.vehicle.id,
                latitude=entity.vehicle.position.latitude,
                longitude=entity.vehicle.position.longitude,
                timestamp=datetime.fromtimestamp(entity.vehicle.timestamp),
            )


async def fetch_realtime_data() -> bytes:
    async with ClientSession(trace_configs=[logger_trace_config()]) as session:
        async with session.get("https://www.zet.hr/gtfs-rt-protobuf") as response:
            response.raise_for_status()
            return await response.read()
