from typing import List, NoReturn, Optional, Union

from ..data_object import DataObject
from .data_provider import DataProvider
from .source import Source

__all__: List[str] = [
    "RestSource",
    "RestDataProvider",
]


class RestSource(Source):
    pass


class RestDataProvider(DataProvider):
    """
    Провайдер для ArcGIS REST.

    Note:
        Ссылку на провайдер можно получить через глобальную переменную :attr:`axipy.provider_manager.rest`.
    """

    @staticmethod
    def _identifier() -> str:
        return "RestDataProvider"

    # noinspection PyPep8Naming
    def get_source(
        self,
        url: str,
        fmt: str = "png32",
        imageSR: int = 102100,
        size: Union[str, tuple] = (1024,1024),
        dpi: int = 96,
        transparent: str = "true",
        layers: str = "",
        alias: Optional[str] = None,
        maxAttempts: int = 0,
    ) -> Source:
        """
        Создает источник данных.

        Args:
          url: Базовый URL.
          fmt: Формат выходного растра.
          imageSR: Код EPSG для выходного растра.
          size: Размер тайлов.
          dpi: DPI.
          transparent: Прозрачность выходного растра.
          layers: Перечень слоев.
          alias: Псевдоним для открываемой таблицы.
          maxAttempts: Максимальное количество попыток запроса. Значение 0 соответствует значению по умолчанию.
        """
        return RestSource(
            Source._provider(self.id),
            Source._alias(alias),
            {
                "src": url,
                "format": fmt,
                "imageSR": imageSR,
                "size": size if isinstance(size, str) else f'{size[0]}*{size[1]}',
                "dpi": dpi,
                "transparent": transparent,
                "layers": layers,
                "maxAttempts": maxAttempts,
            },
        )

    # noinspection PyPep8Naming
    def open(
        self,
        url: str,
        fmt: str = "png32",
        imageSR: int = 102100,
        size: Union[str, tuple] = (1024,1024),
        dpi: int = 96,
        transparent: str = "true",
        layers: str = "",
        alias: Optional[str] = None,
        maxAttempts: int = 0,
    ) -> DataObject:
        """
        Открывает объект данных.

        Args:
          url: Базовый URL.
          fmt: Формат выходного растра.
          imageSR: Код EPSG для выходного растра.
          size: Размер тайлов.
          dpi: DPI.
          transparent: Прозрачность выходного растра.
          layers: Перечень слоев.
          alias: Псевдоним для открываемой таблицы.
          maxAttempts: Максимальное количество попыток запроса. Значение 0 соответствует значению по умолчанию.
        """
        return self.get_source(url, fmt, imageSR, size, dpi, transparent, layers, alias, maxAttempts).open()

    def get_destination(self) -> NoReturn:
        """
        Attention:
            Не поддерживается.

        Raises:
            NotImplementedError
        """
        raise NotImplementedError

    def create_open(self) -> NoReturn:
        """
        Attention:
            Не поддерживается.

        Raises:
            NotImplementedError
        """
        raise NotImplementedError
