# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

"""
Contains validation related utilities
"""


class ValidatorMixin(object):
    """
    A mixin that should be added to classes that require validating user input
    """

    _ARGUMENT_TYPE_MESSAGE = '{name} argument must be {type} based, got {arg!r}'
    _ARGUMENT_CHOICE_MESSAGE = '{name} argument must be in {choices}, got {arg!r}'

    @classmethod
    def validate_in_choice(cls, name, argument, choices):
        """
        Validate ``argument`` is in ``choices``
        """
        if argument not in choices:
            raise TypeError(cls._ARGUMENT_CHOICE_MESSAGE.format(
                name=name, choices=choices, arg=argument))

    @classmethod
    def validate_type(cls, argument_name, argument, expected_type):
        """
        Validate ``argument`` is a subclass of ``expected_type``
        """
        if not issubclass(argument, expected_type):
            raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
                name=argument_name, type=expected_type, arg=argument))

    @classmethod
    def validate_instance(cls, argument_name, argument, expected_type):
        """
        Validate ``argument`` is a instance of ``expected_type``
        """
        if not isinstance(argument, expected_type):
            raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
                name=argument_name, type=expected_type, arg=argument))

    @classmethod
    def validate_callable(cls, argument_name, argument):
        """
        Validate ``argument`` is callable
        """
        if not callable(argument):
            raise TypeError(cls._ARGUMENT_TYPE_MESSAGE.format(
                name=argument_name, type='callable', arg=argument))


def validate_function_arguments(func, func_kwargs):
    """
    Validates all required arguments are supplied to ``func`` and that no additional arguments are
    supplied
    """

    _kwargs_flags = 8

    has_kwargs = func.func_code.co_flags & _kwargs_flags != 0
    args_count = func.func_code.co_argcount

    # all args without the ones with default values
    args = func.func_code.co_varnames[:args_count]
    non_default_args = args[:len(func.func_defaults)] if func.func_defaults else args

    # Check if any args without default values is missing in the func_kwargs
    for arg in non_default_args:
        if arg not in func_kwargs:
            raise ValueError(
                "The argument '{arg}' doest not have a default value, and it "
                "isn't passed to {func.__name__}".format(arg=arg, func=func))

    # check if there are any extra kwargs
    extra_kwargs = [arg for arg in func_kwargs.keys() if arg not in args]

    # assert that the function has kwargs
    if extra_kwargs and not has_kwargs:
        raise ValueError("The following extra kwargs were supplied: {extra_kwargs}".format(
            extra_kwargs=extra_kwargs
        ))
