"""
Settings client for Daisi SDK.
"""

from typing import Optional

import grpc

from protos.v1 import Settings_pb2, Settings_pb2_grpc
from protos.v1.models import SettingsModels_pb2

from ..base_client import BaseClient
from ..config import DaisiConfig
from ..exceptions import DaisiError


class SettingsClient(BaseClient):
    """Client for settings operations."""

    def __init__(self, config: Optional[DaisiConfig] = None) -> None:
        """Initialize settings client.

        Args:
            config: Daisi configuration.
        """
        super().__init__(config)
        self._stub: Optional[Settings_pb2_grpc.SettingsProtoStub] = None

    @property
    def stub(self) -> Settings_pb2_grpc.SettingsProtoStub:
        """Get or create the gRPC stub."""
        if self._stub is None:
            self._stub = Settings_pb2_grpc.SettingsProtoStub(self._get_channel())
        return self._stub

    def get_all(self) -> SettingsModels_pb2.GetAllSettingsResponse:
        """Get all settings.

        Returns:
            Response containing all settings.

        Raises:
            DaisiError: If request fails.
        """
        request = SettingsModels_pb2.GetAllSettingsRequest()

        try:
            return self.stub.GetAll(request, metadata=self._get_metadata())
        except grpc.RpcError as e:
            raise DaisiError(f"Failed to get settings: {e.details()}") from e

    def set_all(
        self, settings: SettingsModels_pb2.SetAllSettingsRequest
    ) -> SettingsModels_pb2.SetAllSettingsResponse:
        """Set all settings.

        Args:
            settings: Settings request with values to set.

        Returns:
            Response indicating success.

        Raises:
            DaisiError: If request fails.
        """
        try:
            return self.stub.SetAll(settings, metadata=self._get_metadata())
        except grpc.RpcError as e:
            raise DaisiError(f"Failed to set settings: {e.details()}") from e
