# 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.

"""
This module provides a ``PlatformConfig`` class to be used for platform configuration management.

A config object can be created from a ``platform_config.conf`` file in the package.
"""

import os
from os.path import expanduser, expandvars
from pathlib import Path
from typing import Optional

from here.platform.environment import Environment
from here.platform.exceptions import ConfigException
from pyhocon import ConfigFactory, ConfigMissingException


class PlatformConfig:
    """
    PlatformConfig provides functions for dealing with the HERE platform
    Config.

    Config can be read from the packaged platform_config.conf file based on platform environment
    """

    def __init__(
        self,
        api: str,
        portal_url: Optional[str] = None,
        status_url: Optional[str] = None,
        platform_status_url: Optional[str] = None,
        account_url: Optional[str] = None,
    ):
        """
        Instantiate the PlatformConfig object.

        :param api: Platform API.
        :param portal_url: (Optional) Platform portal URL.
        :param status_url: (Optional) Status URL.
        :param platform_status_url: (Optional) Platform status api URL.
        :param account_url: (Optional) Account URL.
        """
        self.api = api
        self.portal_url = portal_url
        self.status_url = status_url
        self.platform_status_url = platform_status_url
        self.account_url = account_url

    @classmethod
    def from_environment(cls, environment: Environment) -> "PlatformConfig":
        """
        Return the config object from a specified config file path.

        :param environment: an instance of Environment enum.
        :return: config
        """

        this_dir = Path(__file__).parent
        path = this_dir / environment.name.lower() / "platform_config.conf"
        return cls._from_config_file(os.fspath(path))

    @classmethod
    def _from_config_file(cls, path: str) -> "PlatformConfig":
        """
        Return the config object from a specified config file path.

        :param path: path to a HERE platform platform_config.conf file.
        :return: config
        :raises ConfigException: Erroneous platform_config.conf file in path
        """
        config_path = expanduser(expandvars(path))

        try:
            config_properties = ConfigFactory.parse_file(config_path)
            return PlatformConfig(
                # this will raise ConfigException if key is not present
                api=config_properties.get("here_platform_api"),
                # following params are optional
                portal_url=config_properties.get("here_platform_portal_url", None),
                status_url=config_properties.get("here_status_url", None),
                platform_status_url=config_properties.get("platform_status_api_url", None),
                account_url=config_properties.get("here_account_api_url", None),
            )
        except ConfigMissingException as e:
            raise ConfigException(f"Erroneous {config_path} file: {e}")
