"""Business rules for typed, Agent-routed miner controls.""" from typing import Any from uuid import UUID, uuid4 from app.miner_control.exceptions import ( ControlledMinerNotFound, MinerControlActorRequired, MinerControlUnavailable, ) from app.miner_control.models import ( ControlAgentAvailability, ControlCapability, MinerControlAccepted, MinerControlOperation, MinerControlProjection, ) from app.miner_control.repository import MinerControlRepository KNOWN_MODES = {"low", "normal", "high"} RUNNING_STATES = {"online", "running"} STOPPED_STATES = {"suspended", "stopped"} class MinerControlService: def __init__(self, repository: MinerControlRepository): self.repository = repository @staticmethod def _capability(context: dict) -> ControlCapability: if not context.get("agent_zone_id"): return ControlCapability(state="unavailable", reason="agent_zone_unassigned") if context.get("agent_zone_exists") is not True: return ControlCapability(state="unavailable", reason="agent_zone_missing") if context.get("agent_zone_enabled") is not True: return ControlCapability(state="unavailable", reason="agent_zone_disabled") if not context.get("agent_id"): return ControlCapability(state="unavailable", reason="agent_unavailable") if not context.get("current_ip"): return ControlCapability(state="unavailable", reason="current_ip_missing") if context.get("api3_supported") is False: return ControlCapability(state="unavailable", reason="api3_unsupported") if context.get("api3_supported") is not True: return ControlCapability(state="unknown", reason="api3_support_unknown") payload = context.get("last_payload") or {} if payload.get("control_available") is False: reason = payload.get("control_unavailable_reason") return ControlCapability( state="unavailable", reason=reason if reason == "credentials_missing" else "agent_unavailable", ) if payload.get("control_available") is not True: return ControlCapability( state="unknown", reason="agent_capability_unknown" ) return ControlCapability(state="supported") @staticmethod def _operation(miner_id: UUID, row: dict) -> MinerControlOperation: request = row.get("request_payload") or {} result = row.get("result_payload") or {} mode = result.get("observed_performance_mode") return MinerControlOperation( operation_id=row["operation_id"], miner_id=miner_id, action=request.get("action"), requested_value=request.get("requested_value"), status=row["status"], verification_status=result.get("verification_status"), command_accepted=result.get("command_accepted"), observed_performance_mode=mode if mode in KNOWN_MODES else None, failure_code=result.get("failure_code"), created_at=row["created_at"], claimed_at=row.get("claimed_at"), completed_at=row.get("completed_at"), ) def get_controls(self, miner_id: UUID) -> MinerControlProjection: context = self.repository.get_control_context(miner_id) if not context: raise ControlledMinerNotFound("Miner not found") capability = self._capability(context) runtime = str(context.get("runtime_state") or "").strip().lower() or None service_action = None if capability.state == "supported": if runtime in RUNNING_STATES: service_action = "suspend" elif runtime in STOPPED_STATES: service_action = "resume" configured_mode = str(context.get("configured_performance_mode") or "").lower() return MinerControlProjection( miner_id=miner_id, runtime_state=runtime, performance_mode=(configured_mode if configured_mode in KNOWN_MODES else None), agent=ControlAgentAvailability( state=capability.state, reason=capability.reason, last_checkin_at=context.get("last_checkin_at"), version=context.get("agent_version"), ), service_control=capability, performance_mode_control=capability, available_service_action=service_action, recent_operations=[ self._operation(miner_id, row) for row in self.repository.list_recent(miner_id, limit=5) ], ) def queue_control( self, miner_id: UUID, action: str, *, requested_value: str | None, actor_user_id: UUID, actor_username: str, ) -> MinerControlAccepted: if not actor_user_id: raise MinerControlActorRequired("Authenticated actor UUID is required") context = self.repository.get_control_context(miner_id) if not context: raise ControlledMinerNotFound("Miner not found") capability = self._capability(context) if capability.state != "supported": raise MinerControlUnavailable( capability.reason or "control_capability_not_supported" ) runtime = str(context.get("runtime_state") or "").strip().lower() if action == "suspend" and runtime not in RUNNING_STATES: raise MinerControlUnavailable("miner_not_factually_running") if action == "resume" and runtime not in STOPPED_STATES: raise MinerControlUnavailable("miner_not_factually_stopped") if action == "performance_mode" and requested_value not in KNOWN_MODES: raise MinerControlUnavailable("invalid_performance_mode") operation_id = str(uuid4()) payload: dict[str, Any] = { "schema_version": 1, "miner_id": str(miner_id), "action": action, "requested_value": requested_value, "ip_address": context["current_ip"], } operation = self.repository.enqueue_with_audit( operation_id=operation_id, miner_id=miner_id, agent_id=context["agent_id"], actor_user_id=actor_user_id, actor_username=actor_username, request_payload=payload, audit_payload={ "operation_id": operation_id, "miner_id": str(miner_id), "action": action, "requested_value": requested_value, }, ) return MinerControlAccepted( operation_id=operation["operation_id"], miner_id=miner_id, action=action, requested_value=requested_value, status=operation["status"], created_at=operation["created_at"], )