# Copyright 2016 Google Inc. All Rights Reserved.
#
# 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
#
#     http://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.

"""Helper that converts parameter values to the type expected by the API.

Parameter values that appear in the URL and the query string are usually
converted to native types before being passed to the backend.  This code handles
that conversion and some validation.
"""

# pylint: disable=g-bad-name
from __future__ import absolute_import

from . import errors

__all__ = ['transform_parameter_value']


def _check_enum(parameter_name, value, parameter_config):
  """Checks if an enum value is valid.

  This is called by the transform_parameter_value function and shouldn't be
  called directly.

  This verifies that the value of an enum parameter is valid.

  Args:
    parameter_name: A string containing the name of the parameter, which is
      either just a variable name or the name with the index appended. For
      example 'var' or 'var[2]'.
    value: A string containing the value passed in for the parameter.
    parameter_config: The dictionary containing information specific to the
      parameter in question. This is retrieved from request.parameters in
      the method config.

  Raises:
    EnumRejectionError: If the given value is not among the accepted
      enum values in the field parameter.
  """
  enum_values = [enum['backendValue']
                 for enum in parameter_config['enum'].values()
                 if 'backendValue' in enum]
  if value not in enum_values:
    raise errors.EnumRejectionError(parameter_name, value, enum_values)


def _check_boolean(parameter_name, value, parameter_config):
  """Checks if a boolean value is valid.

  This is called by the transform_parameter_value function and shouldn't be
  called directly.

  This checks that the string value passed in can be converted to a valid
  boolean value.

  Args:
    parameter_name: A string containing the name of the parameter, which is
      either just a variable name or the name with the index appended. For
      example 'var' or 'var[2]'.
    value: A string containing the value passed in for the parameter.
    parameter_config: The dictionary containing information specific to the
      parameter in question. This is retrieved from request.parameters in
      the method config.

  Raises:
    BasicTypeParameterError: If the given value is not a valid boolean
      value.
  """
  if parameter_config.get('type') != 'boolean':
    return

  if value.lower() not in ('1', 'true', '0', 'false'):
    raise errors.BasicTypeParameterError(parameter_name, value, 'boolean')


def _convert_boolean(value):
  """Convert a string to a boolean value the same way the server does.

  This is called by the transform_parameter_value function and shouldn't be
  called directly.

  Args:
    value: A string value to be converted to a boolean.

  Returns:
    True or False, based on whether the value in the string would be interpreted
    as true or false by the server.  In the case of an invalid entry, this
    returns False.
  """
  if value.lower() in ('1', 'true'):
    return True
  return False


# Map to convert parameters from strings to their desired back-end format.
# Anything not listed here will remain a string.  Note that the server
# keeps int64 and uint64 as strings when passed to the backend.
# This maps a type name from the .api method configuration to a (validation
# function, conversion function, descriptive type name) tuple.  The
# descriptive type name is only used in conversion error messages, and the
# names here are chosen to match the error messages from the server.
# Note that the 'enum' entry is special cased.  Enums have 'type': 'string',
# so we have special case code to recognize them and use the 'enum' map
# entry.
_PARAM_CONVERSION_MAP = {'boolean': (_check_boolean,
                                     _convert_boolean,
                                     'boolean'),
                         'int32': (None, int, 'integer'),
                         'uint32': (None, int, 'integer'),
                         'float': (None, float, 'float'),
                         'double': (None, float, 'double'),
                         'enum': (_check_enum, None, None)}


def _get_parameter_conversion_entry(parameter_config):
  """Get information needed to convert the given parameter to its API type.

  Args:
    parameter_config: The dictionary containing information specific to the
      parameter in question. This is retrieved from request.parameters in the
      method config.

  Returns:
    The entry from _PARAM_CONVERSION_MAP with functions/information needed to
    validate and convert the given parameter from a string to the type expected
    by the API.
  """
  entry = _PARAM_CONVERSION_MAP.get(parameter_config.get('type'))

  # Special handling for enum parameters.  An enum's type is 'string', so we
  # need to detect them by the presence of an 'enum' property in their
  # configuration.
  if entry is None and 'enum' in parameter_config:
    entry = _PARAM_CONVERSION_MAP['enum']

  return entry


def transform_parameter_value(parameter_name, value, parameter_config):
  """Validates and transforms parameters to the type expected by the API.

  If the value is a list this will recursively call _transform_parameter_value
  on the values in the list. Otherwise, it checks all parameter rules for the
  the current value and converts its type from a string to whatever format
  the API expects.

  In the list case, '[index-of-value]' is appended to the parameter name for
  error reporting purposes.

  Args:
    parameter_name: A string containing the name of the parameter, which is
      either just a variable name or the name with the index appended, in the
      recursive case. For example 'var' or 'var[2]'.
    value: A string or list of strings containing the value(s) passed in for
      the parameter.  These are the values from the request, to be validated,
      transformed, and passed along to the backend.
    parameter_config: The dictionary containing information specific to the
      parameter in question. This is retrieved from request.parameters in the
      method config.

  Returns:
    The converted parameter value(s).  Not all types are converted, so this
    may be the same string that's passed in.
  """
  if isinstance(value, list):
    # We're only expecting to handle path and query string parameters here.
    # The way path and query string parameters are passed in, they'll likely
    # only be single values or singly-nested lists (no lists nested within
    # lists).  But even if there are nested lists, we'd want to preserve that
    # structure.  These recursive calls should preserve it and convert all
    # parameter values.  See the docstring for information about the parameter
    # renaming done here.
    return [transform_parameter_value('%s[%d]' % (parameter_name, index),
                                      element, parameter_config)
            for index, element in enumerate(value)]

  # Validate and convert the parameter value.
  entry = _get_parameter_conversion_entry(parameter_config)
  if entry:
    validation_func, conversion_func, type_name = entry
    if validation_func:
      validation_func(parameter_name, value, parameter_config)
    if conversion_func:
      try:
        return conversion_func(value)
      except ValueError:
        raise errors.BasicTypeParameterError(parameter_name, value, type_name)

  return value
