"""Deployments resource."""

from __future__ import annotations

import builtins
import time
from collections.abc import Iterator

from .._client import AplikuClient
from .._models import Deployment, LogEntry, PaginatedResponse

_list = builtins.list


class DeploymentsResource:
    def __init__(self, client: AplikuClient) -> None:
        self._client = client

    def _base(self, team: str, app_id: int) -> str:
        return f"/api/team/{team}/applications/{app_id}/deployments"

    def list(
        self, team: str, app_id: int, *, page: int = 1, page_size: int = 20
    ) -> PaginatedResponse[Deployment]:
        """List deployments for an app."""
        return self._client.paginate(
            f"{self._base(team, app_id)}/",
            params={"page": page, "page_size": page_size},
            response_type=Deployment,
        )

    def get(self, team: str, app_id: int, deployment_id: int) -> Deployment:
        """Get a single deployment."""
        data = self._client.get(f"{self._base(team, app_id)}/{deployment_id}/")
        return Deployment.model_validate(data)

    def latest(self, team: str, app_id: int) -> Deployment:
        """Get the latest deployment for an app."""
        data = self._client.get(f"{self._base(team, app_id)}/latest/")
        return Deployment.model_validate(data)

    def logs(
        self,
        team: str,
        app_id: int,
        deployment_id: int,
        after_id: int | None = None,
    ) -> _list[LogEntry]:
        """Get deployment logs, optionally after a given log entry ID."""
        params: dict[str, int] = {}
        if after_id is not None:
            params["after_id"] = after_id
        data = self._client.get(
            f"/api/team/{team}/deployments/{deployment_id}/logs",
            params=params or None,
        )
        results = data if isinstance(data, builtins.list) else data.get("results", [])
        return [LogEntry.model_validate(entry) for entry in results]

    def stream_logs(
        self,
        team: str,
        app_id: int,
        deployment_id: int,
        poll_interval: float = 2.0,
    ) -> Iterator[LogEntry]:
        """Stream deployment logs by polling. Yields log entries as they appear."""
        after_id: int | None = None
        while True:
            entries = self.logs(team, app_id, deployment_id, after_id=after_id)
            for entry in entries:
                yield entry
                after_id = entry.id

            # Check if deployment is still in progress
            deployment = self.get(team, app_id, deployment_id)
            if deployment.status in ("completed", "failed", "aborted"):
                # One final fetch to catch any remaining logs
                final = self.logs(team, app_id, deployment_id, after_id=after_id)
                for entry in final:
                    yield entry
                break

            time.sleep(poll_interval)
