# Copyright (C) 2020-2022 HERE Global B.V. and its affiliate(s).
# All rights reserved.
#
# This software and other materials contain proprietary information
# controlled by HERE and are protected by applicable copyright legislation.
# Any use and utilization of this software and other materials and
# disclosure to any third parties is conditional upon having a separate
# agreement with HERE for the access, use, utilization or disclosure of this
# software. In the absence of such agreement, the use of the software is not
# allowed.
"""Here Map Matcher API module"""
from typing import Dict, Optional

from here.platform.api.base_api import BaseApi
from here.platform.auth import Auth
from here.platform.config.application_config import ApplicationConfig
from here.platform.config.platform_config import PlatformConfig
from here.platform.exceptions import PlatformException


class MapMatchingApi(BaseApi):
    """
    This class provides access to HERE Map Matching APIs.
    """

    def __init__(
        self,
        base_url: str,
        platform_config: PlatformConfig,
        application_config: ApplicationConfig,
        auth: Optional[Auth],
        proxies: Optional[dict] = None,
    ):
        """
        Instantiate ServiceApi object.

        :param base_url: base url
        :param platform_config: a mandatory :class:`PlatformConfig` object to provide
            configuration information for the API.
        :param application_config: a mandatory :class:`ApplicationConfig` object to provide
            configuration information for the API.
        :param auth: an Authentication instance.
        :param proxies: an optional proxy configuration. Defaults to the environment proxy
            configuration.
        """
        super().__init__(
            platform_config=platform_config,
            application_config=application_config,
            auth=auth,
            proxies=proxies,
        )
        self.base_url = base_url

    @property
    def headers(self) -> dict:
        """
        Return HTTP request headers with Bearer token in ``Authorization``
        field.

        :return: authorization tokens
        """
        return {"Authorization": f"Bearer {self.auth.token}"} if self.auth else {}

    def map_matcher_map_versions(self):
        """
        List of map versions
        :return: map versions
        :raises PlatformException: If platform responds with an HTTP error.
        """
        path = "maps/versions"
        url = f"https://mapmatcher.hereapi.com/v1/{path}"
        resp = self.get(url, headers=self.headers)
        if resp.status_code == 200:
            map_versions = resp.text
            return map_versions
        else:
            raise PlatformException(resp)

    def get_map_matcher_map_version(self, version: str) -> str:
        """
        Details of specific map version
        :param version: version to use or `latest` to use the latest available version
        :return: map version
        :raises PlatformException: If platform responds with an HTTP error.
        """
        path = f"maps/versions/{version}"
        url = f"https://mapmatcher.hereapi.com/v1/{path}"
        resp = self.get(url, headers=self.headers)
        if resp.status_code == 200:
            map_version = resp.text
            return map_version
        else:
            raise PlatformException(resp)

    def get_matched_path(
        self, version: str, data: Dict, road_access: str, interpolate: bool
    ) -> str:
        """
        Get matched path corresponding to the latitude and longitude.
        :param data: dict of lat and long
        :param version: map version to use or `latest` to use the latest available version.
        :param road_access: map matching mode to use. Valid values are `unrestricted` and `car`
        :param interpolate: specifies whether to add interpolated points to sub-paths in order to
        retrieve the full path geometry. Default value is `False`
        :return: string of matched path
        :raises PlatformException: If platform responds with an HTTP error.
        """
        path = f"maps/versions/{version}"
        url = f"https://mapmatcher.hereapi.com/v1/{path}/matchedPath"
        params = {"roadAccess": road_access, "interpolate": str(interpolate).lower()}
        resp = self.post(url=url, headers=self.headers, data=data, params=params)
        if resp.status_code == 200:
            matched_path = resp.text
            return matched_path
        else:
            raise PlatformException(resp)
