"""Transport-neutral, expiring robot commands."""

from __future__ import annotations

from dataclasses import dataclass, field
from types import MappingProxyType
from typing import Any, Mapping
from uuid import uuid4
from time import time_ns


@dataclass(frozen=True, slots=True)
class RobotCommand:
    device_id: str
    action: str
    valid_until_ns: int
    sequence: int
    arguments: Mapping[str, Any] = field(default_factory=dict)
    command_id: str = field(default_factory=lambda: str(uuid4()))

    def __post_init__(self) -> None:
        if not self.device_id:
            raise ValueError("device_id must not be empty")
        if not self.action:
            raise ValueError("action must not be empty")
        if self.valid_until_ns <= 0:
            raise ValueError("valid_until_ns must be positive Unix time")
        if self.sequence < 0:
            raise ValueError("sequence must not be negative")
        if not self.command_id:
            raise ValueError("command_id must not be empty")
        object.__setattr__(self, "arguments", MappingProxyType(dict(self.arguments)))


@dataclass(frozen=True, slots=True)
class ApprovedRobotCommand:
    """A command that has passed the trusted safety-gate boundary."""

    command: RobotCommand
    approved_by: str
    approved_at_ns: int = field(default_factory=time_ns)

    def __post_init__(self) -> None:
        if not self.approved_by:
            raise ValueError("approved_by must not be empty")
        if self.approved_at_ns <= 0:
            raise ValueError("approved_at_ns must be positive Unix time")
