# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""The envparse module defines an environment variable parser."""

import argparse
import os
from typing import Callable, Dict, Generic, IO, List, Mapping
from typing import NamedTuple, Optional, TypeVar


class EnvNamespace(argparse.Namespace):  # pylint: disable=too-few-public-methods
    """Base class for parsed environment variable namespaces."""


T = TypeVar('T')
TypeConversion = Callable[[str], T]


class VariableDescriptor(NamedTuple, Generic[T]):
    name: str
    type: TypeConversion[T]
    default: Optional[T]


class EnvironmentValueError(Exception):
    """Exception indicating a bad type conversion on an environment variable.

    Stores a reference to the lower-level exception from the type conversion
    function through the __cause__ attribute for more detailed information on
    the error.
    """
    def __init__(self, variable: str, value: str):
        self.variable: str = variable
        self.value: str = value
        super().__init__(
            f'Bad value for environment variable {variable}: {value}')


class EnvironmentParser:
    """Parser for environment variables.

    Args:
        prefix: If provided, checks that all registered environment variables
          start with the specified string.
        error_on_unrecognized: If True and prefix is provided, will raise an
          exception if the environment contains a variable with the specified
          prefix that is not registered on the EnvironmentParser.

    Example:

        parser = envparse.EnvironmentParser(prefix='PW_')
        parser.add_var('PW_LOG_LEVEL')
        parser.add_var('PW_LOG_FILE', type=envparse.FileType('w'))
        parser.add_var('PW_USE_COLOR', type=envparse.strict_bool, default=False)
        env = parser.parse_env()

        configure_logging(env.PW_LOG_LEVEL, env.PW_LOG_FILE)
    """
    def __init__(self,
                 prefix: Optional[str] = None,
                 error_on_unrecognized: bool = True) -> None:
        self._prefix: Optional[str] = prefix
        self._error_on_unrecognized: bool = error_on_unrecognized
        self._variables: Dict[str, VariableDescriptor] = {}
        self._allowed_suffixes: List[str] = []

    def add_var(
        self,
        name: str,
        # pylint: disable=redefined-builtin
        type: TypeConversion[T] = str,  # type: ignore
        # pylint: enable=redefined-builtin
        default: Optional[T] = None,
    ) -> None:
        """Registers an environment variable.

        Args:
            name: The environment variable's name.
            type: Type conversion for the variable's value.
            default: Default value for the variable.

        Raises:
            ValueError: If prefix was provided to the constructor and name does
              not start with the prefix.
        """
        if self._prefix is not None and not name.startswith(self._prefix):
            raise ValueError(
                f'Variable {name} does not have prefix {self._prefix}')

        self._variables[name] = VariableDescriptor(
            name,
            type,  # type: ignore
            default)  # type: ignore

    def add_allowed_suffix(self, suffix: str) -> None:
        """Registers an environmant variable name suffix to be allowed."""

        self._allowed_suffixes.append(suffix)

    def parse_env(self,
                  env: Optional[Mapping[str, str]] = None) -> EnvNamespace:
        """Parses known environment variables into a namespace.

        Args:
            env: Dictionary of environment variables. Defaults to os.environ.

        Raises:
            EnvironmentValueError: If the type conversion fails.
        """
        if env is None:
            env = os.environ

        namespace = EnvNamespace()

        for var, desc in self._variables.items():
            if var not in env:
                val = desc.default
            else:
                try:
                    val = desc.type(env[var])
                except Exception as err:
                    raise EnvironmentValueError(var, env[var]) from err

            setattr(namespace, var, val)

        allowed_suffixes = tuple(self._allowed_suffixes)
        for var in env:
            if (not hasattr(namespace, var)
                    and (self._prefix is None or var.startswith(self._prefix))
                    and var.endswith(allowed_suffixes)):
                setattr(namespace, var, env[var])

        if self._prefix is not None and self._error_on_unrecognized:
            for var in env:
                if (var.startswith(self._prefix) and var not in self._variables
                        and not var.endswith(allowed_suffixes)):
                    raise ValueError(
                        f'Unrecognized environment variable {var}')

        return namespace

    def __repr__(self) -> str:
        return f'{type(self).__name__}(prefix={self._prefix})'


# List of emoji which are considered to represent "True".
_BOOLEAN_TRUE_EMOJI = set([
    '✔️',
    '👍',
    '👍🏻',
    '👍🏼',
    '👍🏽',
    '👍🏾',
    '👍🏿',
    '💯',
])


def strict_bool(value: str) -> bool:
    return (value == '1' or value.lower() == 'true'
            or value in _BOOLEAN_TRUE_EMOJI)


# TODO(mohrr) Switch to Literal when no longer supporting Python 3.7.
# OpenMode = Literal['r', 'rb', 'w', 'wb']
OpenMode = str


class FileType:
    def __init__(self, mode: OpenMode) -> None:
        self._mode: OpenMode = mode

    def __call__(self, value: str) -> IO:
        return open(value, self._mode)
