from __future__ import annotations

import json
from dataclasses import dataclass

import pytest

from omni.auth.service_account import ServiceAccount
from omni.auth.signer import SideroSigner


class _DummySig:
    def __bytes__(self) -> bytes:
        return b"signature-bytes"


@dataclass
class _DummyKey:
    fingerprint: str = "FINGERPRINT123"

    def sign(self, payload: bytes, detached: bool = True) -> _DummySig:  # noqa: ARG002
        return _DummySig()


@pytest.fixture()
def signer() -> SideroSigner:
    account = ServiceAccount(name="svc-account", private_key=_DummyKey())  # type: ignore[arg-type]
    return SideroSigner(account)


def test_api_signature_header_shape(monkeypatch: pytest.MonkeyPatch, signer: SideroSigner) -> None:
    monkeypatch.setattr("time.time", lambda: 1700000000)
    signed = signer.sign_api_request(
        method_path="/omni.resources.ResourceService/Get",
        metadata={"cluster": "c1", "namespace": "default"},
    )

    assert "Grpc-Metadata-x-sidero-timestamp" in signed.headers
    assert "Grpc-Metadata-x-sidero-payload" in signed.headers
    assert "Grpc-Metadata-x-sidero-signature" in signed.headers

    payload = json.loads(signed.payload)
    assert payload["method"] == "/omni.resources.ResourceService/Get"
    assert payload["headers"]["cluster"] == ["c1"]
    assert payload["headers"]["nodes"] is None


def test_image_signature_payload(monkeypatch: pytest.MonkeyPatch, signer: SideroSigner) -> None:
    monkeypatch.setattr("time.time", lambda: 1700000000)
    signed = signer.sign_image_request("GET", "/image/installer.raw", b"")
    assert "x-sidero-timestamp" in signed.headers
    assert "x-sidero-signature" in signed.headers
    assert "\n" in signed.payload
