"""NI-DAQmx persisted scale classes."""

from nidaqmx import utils
from nidaqmx.scale import _ScaleAlternateConstructor

__all__ = ["PersistedScale"]


class PersistedScale:
    """Represents a saved DAQmx custom scale.

    Use the DAQmx Persisted Scale properties to query information about
    programmatically saved custom scales.
    """

    __slots__ = ["_name", "_interpreter", "__weakref__"]

    def __init__(self, name, *, grpc_options=None):
        """Initialize a new PersistedScale.

        Args:
            name (str): Specifies the name of the saved scale.
            grpc_options (Optional[:class:`~nidaqmx.GrpcSessionOptions`]): Specifies
                the gRPC session options.
        """
        self._name = name
        self._interpreter = utils._select_interpreter(grpc_options)

    def __eq__(self, other):  # noqa: D105 - Missing docstring in magic method (auto-generated noqa)
        if isinstance(other, self.__class__):
            return self._name == other._name
        return False

    def __hash__(self):  # noqa: D105 - Missing docstring in magic method (auto-generated noqa)
        return hash(self._name)

    def __ne__(self, other):  # noqa: D105 - Missing docstring in magic method (auto-generated noqa)
        return not self.__eq__(other)

    def __repr__(self):  # noqa: D105 - Missing docstring in magic method (auto-generated noqa)
        return f"PersistedScale(name={self._name})"

    @property
    def name(self):
        """str: Indicates the name of the custom scale."""
        return self._name

    @property
    def author(self):
        """str: Indicates the author of the custom scale."""
        val = self._interpreter.get_persisted_scale_attribute_string(self._name, 0x22D4)
        return val

    @property
    def allow_interactive_editing(self):
        """bool: Indicates whether the custom scale can be edited in the DAQ Assistant."""
        val = self._interpreter.get_persisted_scale_attribute_bool(self._name, 0x22D5)
        return val

    @property
    def allow_interactive_deletion(self):
        """bool: Indicates whether the custom scale can be deleted through MAX."""
        val = self._interpreter.get_persisted_scale_attribute_bool(self._name, 0x22D6)
        return val

    def delete(self):
        """Deletes this custom scale from MAX.

        This function does not remove the custom scale from virtual
        channels that use it.
        """
        self._interpreter.delete_saved_scale(self._name)

    def load(self):
        """Loads this custom scale.

        Returns:
            nidaqmx.scale.Scale: Indicates the loaded Scale object.
        """
        return _ScaleAlternateConstructor(self._name, self._interpreter)


class _PersistedScaleAlternateConstructor(PersistedScale):
    """Provide an alternate constructor for the PersistedScale object.

    This is a private API used to instantiate a PersistedScale with an existing interpreter.
    """

    # Setting __slots__ avoids TypeError: __class__ assignment: 'Base' object layout differs from 'Derived'.  # noqa: W505 - doc line too long (108 > 100 characters) (auto-generated noqa)
    __slots__ = ()

    def __init__(self, name, interpreter):
        """Initialize a new PersistedScale with an existing interpreter.

        Args:
            name: Specifies the name of the PersistedScale.
            interpreter: Specifies the interpreter instance.

        """
        self._name = name
        self._interpreter = interpreter

        # Use meta-programming to change the type of this object to PersistedScale,
        # so the user isn't confused when doing introspection.
        self.__class__ = PersistedScale  # type: ignore[assignment]
