"""
Synchronous client for the lf-seq-interp service.
Used by the orchestrator to interpret .seq files on behalf of the GUI.
"""
from __future__ import annotations

import time
import requests


class SeqInterpError(Exception):
    pass


class SeqInterpClient:
    def __init__(self, base_url: str = "http://seq-interp:7475") -> None:
        self.base_url = base_url.rstrip("/")

    def interpret_and_wait(
        self,
        file_bytes: bytes,
        filename: str,
        poll_interval: float = 2.0,
        timeout: float = 120.0,
    ) -> dict:
        """
        Upload a .seq file, poll until interpretation is done, return full result dict.

        Returns dict with keys: task_id, status, metadata, post_json, waveforms, ...
        Raises SeqInterpError on HTTP errors or timeout.
        """
        # 1. Upload
        try:
            r = requests.post(
                f"{self.base_url}/interpret/",
                files={"file": (filename, file_bytes, "application/octet-stream")},
                timeout=30.0,
            )
            r.raise_for_status()
        except requests.RequestException as exc:
            raise SeqInterpError(f"Failed to upload to seq-interp: {exc}") from exc

        task_id = r.json().get("task_id")
        if not task_id:
            raise SeqInterpError("seq-interp did not return a task_id")

        # 2. Poll for result
        deadline = time.monotonic() + timeout
        while time.monotonic() < deadline:
            time.sleep(poll_interval)
            try:
                r = requests.get(
                    f"{self.base_url}/result/{task_id}",
                    timeout=10.0,
                )
            except requests.RequestException as exc:
                raise SeqInterpError(f"Poll error: {exc}") from exc

            if r.status_code == 200:
                return r.json()
            if r.status_code == 202:
                continue  # still processing
            raise SeqInterpError(
                f"seq-interp returned HTTP {r.status_code}: {r.text[:200]}"
            )

        raise SeqInterpError(
            f"seq-interp interpretation timed out after {timeout}s (task_id={task_id})"
        )
