# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hp.com>
#
# 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.
import datetime
import jsonschema
from jsonschema import _utils


def type_draft3(validator, types, instance, schema):
    types = _utils.ensure_list(types)

    # NOTE(kiall): A datetime object is not a string, but is still valid.
    if ('format' in schema and schema['format'] == 'date-time'
            and isinstance(instance, datetime.datetime)):
        return

    all_errors = []
    for index, type in enumerate(types):
        if type == "any":
            return
        if validator.is_type(type, "object"):
            errors = list(validator.descend(instance, type, schema_path=index))
            if not errors:
                return
            all_errors.extend(errors)
        else:
            if validator.is_type(instance, type):
                return
    else:
        yield jsonschema.ValidationError(
            _utils.types_msg(instance, types), context=all_errors,
        )


def oneOf_draft3(validator, oneOf, instance, schema):
        # Backported from Draft4 to Draft3
        subschemas = iter(oneOf)
        first_valid = next(
            (s for s in subschemas if validator.is_valid(instance, s)), None,
        )

        if first_valid is None:
            yield jsonschema.ValidationError(
                "%r is not valid under any of the given schemas." % (instance,)
            )
        else:
            more_valid = [s for s in subschemas
                          if validator.is_valid(instance, s)]
            if more_valid:
                more_valid.append(first_valid)
                reprs = ", ".join(repr(schema) for schema in more_valid)
                yield jsonschema.ValidationError(
                    "%r is valid under each of %s" % (instance, reprs)
                )


def type_draft4(validator, types, instance, schema):
    types = _utils.ensure_list(types)

    # NOTE(kiall): A datetime object is not a string, but is still valid.
    if ('format' in schema and schema['format'] == 'date-time'
            and isinstance(instance, datetime.datetime)):
        return

    if not any(validator.is_type(instance, type) for type in types):
        yield jsonschema.ValidationError(_utils.types_msg(instance, types))
