"""Deterministic mock google adapter for tests.

Mirrors GoogleAdapter's Protocol surface. No network calls and no
GEMINI_API_KEY required. Supports nbp/flash (image, synchronous) and
veo-3.1 (video, async-shaped). Used when RECOIL_PROVIDER_MODE=test.
"""

from __future__ import annotations

from typing import Optional

from recoil.execution.providers.base import (
    PollRequest,
    PollResult,
    ProviderJob,
    SubmitRequest,
    UnifiedVideoPayload,
)
from recoil.execution.providers.payload_hints import coerce_to_dict


class MockGoogleAdapter:
    provider_id = "google"
    supported_models = ["nbp", "flash", "veo-3.1"]
    auth_env_var = "GEMINI_API_KEY"
    base_url = "mock://generativelanguage.googleapis.com"
    max_prompt_chars = None
    status = "primary"
    capabilities = {
        "t2v": True,
        "i2v": True,
        "r2v": False,
        "end_frame": False,
        "audio": True,
        "negative_prompt": False,
        "resolution_480p": False,
        "resolution_720p": True,
        "resolution_1080p": False,
    }

    def build_submit(self, payload: UnifiedVideoPayload, tier: str) -> SubmitRequest:
        modality = coerce_to_dict(payload.hints).get("modality", "video")
        if modality == "image":
            return SubmitRequest(
                method="POST",
                url=f"{self.base_url}/image-synchronous",
                headers={},
                body={
                    "prompt": payload.prompt,
                    "model": payload.model_id,
                    "tier": tier,
                },
            )
        return SubmitRequest(
            method="POST",
            url=f"{self.base_url}/video-veo",
            headers={},
            body={"prompt": payload.prompt, "model": payload.model_id, "tier": tier},
        )

    def parse_submit(self, resp, payload, tier):
        modality = coerce_to_dict(payload.hints).get("modality", "video")
        return ProviderJob(
            provider_id=self.provider_id,
            model_id=payload.model_id,
            native_id=resp.get("native_id", "mock-google-id"),
            tier=tier,
            duration_s=payload.duration_s,
            resolution=payload.resolution,
            native_state={
                "modality": modality,
                "operation": None,
                "image_bytes": resp.get("image_bytes") if modality == "image" else None,
                "video_url": resp.get("video_url") if modality == "video" else None,
            },
        )

    def build_poll(self, job):
        return PollRequest(method="GET", url=f"{self.base_url}/noop", headers={})

    def parse_poll(self, resp, job):
        if job.native_state.get("modality") == "image":
            return PollResult(status="COMPLETED", raw=resp or {})
        # Mock: any non-empty resp marks completion.
        if resp and resp.get("done", True):
            return PollResult(status="COMPLETED", raw=resp)
        return PollResult(status="IN_PROGRESS", raw=resp or {})

    def build_result_fetch(self, job) -> Optional[PollRequest]:
        return None

    def parse_result(self, resp, job):
        if job.native_state.get("modality") == "image":
            return PollResult(
                status="COMPLETED",
                video_url=None,
                raw={"image_bytes": job.native_state.get("image_bytes") or b"\x00mock"},
            )
        return PollResult(
            status="COMPLETED",
            video_url=job.native_state.get("video_url") or "mock://google/video.mp4",
            raw=resp or {},
        )

    def compute_cost(self, duration_s: float, tier: str, profile: dict) -> float:
        modality = (profile or {}).get("modality") or "video"
        if modality == "image":
            return float((profile or {}).get("image_cost", 0.04))
        return 0.50 * float(duration_s)


ADAPTER = MockGoogleAdapter()
__all__ = ["MockGoogleAdapter", "ADAPTER"]
