from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Dict, List

from sila2.framework import FullyQualifiedIdentifier
from sila2.server import FeatureImplementationBase

from .silaservice_types import GetFeatureDefinition_Responses, SetServerName_Responses


class SiLAServiceBase(FeatureImplementationBase, ABC):
    @abstractmethod
    def get_ServerName(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
        Human readable name of the SiLA Server. The name can be set using the 'Set Server Name' command.

        :param metadata: The SiLA Client Metadata attached to the call
        :return: Human readable name of the SiLA Server. The name can be set using the 'Set Server Name' command.
        """
        pass

    @abstractmethod
    def get_ServerType(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
          The type of this server. It, could be, e.g., in the case of a SiLA Device the model name.
        It is specified by the implementer of the SiLA Server and MAY not be unique.

          :param metadata: The SiLA Client Metadata attached to the call
          :return: The type of this server. It, could be, e.g., in the case of a SiLA Device the model name.
        It is specified by the implementer of the SiLA Server and MAY not be unique.
        """
        pass

    @abstractmethod
    def get_ServerUUID(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
          Globally unique identifier that identifies a SiLA Server. The Server UUID MUST be generated once
        and remain the same for all times.

          :param metadata: The SiLA Client Metadata attached to the call
          :return: Globally unique identifier that identifies a SiLA Server. The Server UUID MUST be generated once
        and remain the same for all times.
        """
        pass

    @abstractmethod
    def get_ServerDescription(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
        Description of the SiLA Server. This should include the use and purpose of this SiLA Server.

        :param metadata: The SiLA Client Metadata attached to the call
        :return: Description of the SiLA Server. This should include the use and purpose of this SiLA Server.
        """
        pass

    @abstractmethod
    def get_ServerVersion(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
          Returns the version of the SiLA Server. A "Major" and a "Minor" version number (e.g. 1.0) MUST be provided,
        a Patch version number MAY be provided. Optionally, an arbitrary text, separated by an underscore MAY be
        appended, e.g. “3.19.373_mighty_lab_devices”.

          :param metadata: The SiLA Client Metadata attached to the call
          :return: Returns the version of the SiLA Server. A "Major" and a "Minor" version number (e.g. 1.0) MUST be provided,
        a Patch version number MAY be provided. Optionally, an arbitrary text, separated by an underscore MAY be
        appended, e.g. “3.19.373_mighty_lab_devices”.
        """
        pass

    @abstractmethod
    def get_ServerVendorURL(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> str:
        """
          Returns the URL to the website of the vendor or the website of the product of this SiLA Server.
        This URL SHOULD be accessible at all times.
        The URL is a Uniform Resource Locator as defined in RFC 1738.

          :param metadata: The SiLA Client Metadata attached to the call
          :return: Returns the URL to the website of the vendor or the website of the product of this SiLA Server.
        This URL SHOULD be accessible at all times.
        The URL is a Uniform Resource Locator as defined in RFC 1738.
        """
        pass

    @abstractmethod
    def get_ImplementedFeatures(self, *, metadata: Dict[FullyQualifiedIdentifier, Any]) -> List[str]:
        """
          Returns a list of fully qualified Feature identifiers of all implemented Features of this SiLA Server.
        This list SHOULD remain the same throughout the lifetime of the SiLA Server.

          :param metadata: The SiLA Client Metadata attached to the call
          :return: Returns a list of fully qualified Feature identifiers of all implemented Features of this SiLA Server.
        This list SHOULD remain the same throughout the lifetime of the SiLA Server.
        """
        pass

    @abstractmethod
    def GetFeatureDefinition(
        self, FeatureIdentifier: str, *, metadata: Dict[FullyQualifiedIdentifier, Any]
    ) -> GetFeatureDefinition_Responses:
        """
          Get the Feature Definition of an implemented Feature by its fully qualified Feature Identifier.
        This command has no preconditions and no further dependencies and can be called at any time.


          :param FeatureIdentifier: The fully qualified Feature identifier for which the Feature definition shall be retrieved.

          :param metadata: The SiLA Client Metadata attached to the call

          :return:

              - FeatureDefinition: The Feature definition in XML format (according to the Feature Definition Schema).


        """
        pass

    @abstractmethod
    def SetServerName(
        self, ServerName: str, *, metadata: Dict[FullyQualifiedIdentifier, Any]
    ) -> SetServerName_Responses:
        """
          Sets a human readable name to the Server Name Property.Command has no preconditions and
        no further dependencies and can be called at any time.


          :param ServerName: The human readable name to assign to the SiLA Server.

          :param metadata: The SiLA Client Metadata attached to the call

        """
        pass
