from __future__ import annotations
from typing import Protocol, runtime_checkable, Sequence
from zempy.zosapi.common.enums.settings_data_type import SettingsDataType

@runtime_checkable
class ISettingsData(Protocol):
    """Methods and interfaces for storing and retrieving user-defined settings.

    This protocol mirrors the ZOSAPI.Common.ISettingsData surface with
    Pythonic tuple returns for methods that have out-parameters in .NET.
    """

    # --- Properties ---
    @property
    def NumberOfSettings(self) -> int:
        """Gets the total number of settings currently stored via the API."""
        ...

    # --- Keys & type info ---
    def GetKeys(self) -> list[str]:
        """Gets an array of all keys currently stored."""
        ...

    def GetEntryType(self, key: str) -> tuple[bool, SettingsDataType, bool, int]:
        """Gets information about the data associated with the specified key.

        Returns (ok, data_type, is_array, array_size).
        """
        ...


    def GetDoubleValue(self, key: str) -> tuple[bool, float]: ...
    def GetIntegerValue(self, key: str) -> tuple[bool, int]: ...
    def GetFloatValue(self, key: str) -> tuple[bool, float]: ...
    def GetStringValue(self, key: str) -> tuple[bool, str]: ...
    def GetByteValue(self, key: str) -> tuple[bool, int]: ...  # Python byte -> int(0..255)
    def GetBooleanValue(self, key: str) -> tuple[bool, bool]: ...

    def SetDoubleValue(self, key: str, val: float) -> None: ...
    def SetIntegerValue(self, key: str, val: int) -> None: ...
    def SetFloatValue(self, key: str, val: float) -> None: ...
    def SetStringValue(self, key: str, val: str) -> None: ...
    def SetByteValue(self, key: str, val: int) -> None: ...
    def SetBooleanValue(self, key: str, val: bool) -> None: ...

    # --- Arrays ---
    def GetDoubleArray(self, key: str, Size: int) -> tuple[bool, list[float]]: ...
    def GetIntegerArray(self, key: str, Size: int) -> tuple[bool, list[int]]: ...
    def GetFloatArray(self, key: str, Size: int) -> tuple[bool, list[float]]: ...
    def GetByteArray(self, key: str, Size: int) -> tuple[bool, list[int]]: ...
    def GetBooleanArray(self, key: str, Size: int) -> tuple[bool, list[bool]]: ...

    def SetDoubleArray(self, key: str, Size: int, val: Sequence[float]) -> None: ...
    def SetIntegerArray(self, key: str, Size: int, val: Sequence[int]) -> None: ...
    def SetFloatArray(self, key: str, Size: int, val: Sequence[float]) -> None: ...
    def SetByteArray(self, key: str, Size: int, val: Sequence[int]) -> None: ...
    def SetBooleanArray(self, key: str, Size: int, val: Sequence[bool]) -> None: ...
