from __future__ import annotations

from .base import SubclientBase
from ..schemas import (
    CommandDryRunRequest,
    CommandDryRunResponse,
    ReportGenerationResponse,
)


class CommandsClient(SubclientBase):

    async def start_dryrun_commands(
        self, commands: list[CommandDryRunRequest]
    ) -> ReportGenerationResponse:
        response = await self._client.post(
            self._client.path("/commands/data/dry-run"),
            json=[self._client.dump(command) for command in commands],
        )
        return self._client.parse(response, ReportGenerationResponse)

    async def get_dryrun_commands_result(
        self,
        job_id: str,
        timeout_seconds: float | None = 300.0,
        poll_interval_seconds: float = 1.0,
        wait_for_ready: bool = True,
    ) -> CommandDryRunResponse:
        if not job_id:
            raise ValueError("job_id must be a non-empty string")
        if timeout_seconds is not None and timeout_seconds < 0:
            raise ValueError("timeout_seconds must be non-negative or None")
        if poll_interval_seconds <= 0:
            raise ValueError("poll_interval_seconds must be greater than 0")

        if wait_for_ready:
            await self._client.bgtasks.wait_for_task(
                job_id=job_id,
                timeout_seconds=timeout_seconds,
                poll_interval_seconds=poll_interval_seconds,
            )

        response = await self._client.get(
            self._client.path(f"/commands/data/dry-run/{job_id}")
        )
        return self._client.parse(response, CommandDryRunResponse)

    async def dryrun_commands(
        self,
        commands: list[CommandDryRunRequest],
        timeout_seconds: float | None = 300.0,
        poll_interval_seconds: float = 1.0,
        wait_for_ready: bool = True,
    ) -> CommandDryRunResponse:
        job = await self.start_dryrun_commands(commands)
        return await self.get_dryrun_commands_result(
            job_id=job.job_id,
            timeout_seconds=timeout_seconds,
            poll_interval_seconds=poll_interval_seconds,
            wait_for_ready=wait_for_ready,
        )

    async def commands_dryrun(
        self,
        commands: list[CommandDryRunRequest],
        timeout_seconds: float | None = 300.0,
        poll_interval_seconds: float = 1.0,
        wait_for_ready: bool = True,
    ) -> CommandDryRunResponse:
        return await self.dryrun_commands(
            commands=commands,
            timeout_seconds=timeout_seconds,
            poll_interval_seconds=poll_interval_seconds,
            wait_for_ready=wait_for_ready,
        )
