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

import re

from aria.utils.collections import OrderedDict
from aria.utils.formatting import safe_repr
from aria.utils.type import full_type_name
from aria.utils.imports import import_fullname
from aria.parser import implements_specification
from aria.parser.presentation import (get_locator, validate_primitive)
from aria.parser.validation import Issue

from .functions import get_function
from ..presentation.types import get_type_by_full_or_shorthand_name


#
# DataType
#

def get_inherited_constraints(context, presentation):
    """
    If we don't have constraints, will return our parent's constraints (if we have one),
    recursively.

    Implication: if we define even one constraint, the parent's constraints will not be inherited.
    """

    constraints = presentation.constraints

    if constraints is None:
        # If we don't have any, use our parent's
        parent = presentation._get_parent(context)
        parent_constraints = get_inherited_constraints(context, parent) \
            if parent is not None else None
        if parent_constraints is not None:
            constraints = parent_constraints

    return constraints


def coerce_data_type_value(context, presentation, data_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                           aspect):
    """
    Handles the ``_coerce_data()`` hook for complex data types.

    There are two kinds of handling:

    1. If we have a primitive type as our great ancestor, then we do primitive type coersion, and
       just check for constraints.

    2. Otherwise, for normal complex data types we return the assigned property values while making
       sure they are defined in our type. The property definition's default value, if available,
       will be used if we did not assign it. We also make sure that required definitions indeed end
       up with a value.
    """

    primitive_type = data_type._get_primitive_ancestor(context)
    if primitive_type is not None:
        # Must be coercible to primitive ancestor
        value = coerce_to_primitive(context, presentation, primitive_type, constraints, value,
                                    aspect)
    else:
        definitions = data_type._get_properties(context)
        if isinstance(value, dict):
            temp = OrderedDict()

            # Fill in our values, but make sure they are defined
            for name, v in value.iteritems():
                if name in definitions:
                    definition = definitions[name]
                    definition_type = definition._get_type(context)
                    definition_entry_schema = definition.entry_schema
                    definition_constraints = definition._get_constraints(context)
                    temp[name] = coerce_value(context, presentation, definition_type,
                                              definition_entry_schema, definition_constraints, v,
                                              aspect)
                else:
                    context.validation.report(
                        'assignment to undefined property "%s" in type "%s" in "%s"'
                        % (name, data_type._fullname, presentation._fullname),
                        locator=get_locator(v, value, presentation), level=Issue.BETWEEN_TYPES)

            # Fill in defaults from the definitions, and check if required definitions have not been
            # assigned
            for name, definition in definitions.iteritems():
                if (temp.get(name) is None) and hasattr(definition, 'default') \
                    and (definition.default is not None):
                    definition_type = definition._get_type(context)
                    definition_entry_schema = definition.entry_schema
                    definition_constraints = definition._get_constraints(context)
                    temp[name] = coerce_value(context, presentation, definition_type,
                                              definition_entry_schema, definition_constraints,
                                              definition.default, 'default')

                if getattr(definition, 'required', False) and (temp.get(name) is None):
                    context.validation.report(
                        'required property "%s" in type "%s" is not assigned a value in "%s"'
                        % (name, data_type._fullname, presentation._fullname),
                        locator=presentation._get_child_locator('definitions'),
                        level=Issue.BETWEEN_TYPES)

            value = temp
        elif value is not None:
            context.validation.report('value of type "%s" is not a dict in "%s"'
                                      % (data_type._fullname, presentation._fullname),
                                      locator=get_locator(value, presentation),
                                      level=Issue.BETWEEN_TYPES)
            value = None

    return value


def validate_data_type_name(context, presentation):
    """
    Makes sure the complex data type's name is not that of a built-in type.
    """

    name = presentation._name
    if get_primitive_data_type(name) is not None:
        context.validation.report('data type name is that of a built-in type: %s'
                                  % safe_repr(name),
                                  locator=presentation._locator, level=Issue.BETWEEN_TYPES)


#
# PropertyDefinition, AttributeDefinition, EntrySchema, DataType
#

def get_data_type(context, presentation, field_name, allow_none=False):
    """
    Returns the type, whether it's a complex data type (a DataType instance) or a primitive (a
    Python primitive type class).

    If the type is not specified, defaults to :class:`str`, per note in section 3.2.1.1 of the
    `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #_Toc379455072>`__
    """

    type_name = getattr(presentation, field_name)

    if type_name is None:
        if allow_none:
            return None
        else:
            return str

    # Make sure not derived from self
    if type_name == presentation._name:
        return None

    # Avoid circular definitions
    container_data_type = get_container_data_type(presentation)
    if (container_data_type is not None) and (container_data_type._name == type_name):
        return None

    # Try complex data type
    data_type = get_type_by_full_or_shorthand_name(context, type_name, 'data_types')
    if data_type is not None:
        return data_type

    # Try primitive data type
    return get_primitive_data_type(type_name)


#
# PropertyDefinition, EntrySchema
#

def get_property_constraints(context, presentation):
    """
    If we don't have constraints, will return our type's constraints (if we have one), recursively.

    Implication: if we define even one constraint, the type's constraints will not be inherited.
    """

    constraints = presentation.constraints

    if constraints is None:
        # If we don't have any, use our type's
        the_type = presentation._get_type(context)
        type_constraints = the_type._get_constraints(context) \
            if hasattr(the_type, '_get_constraints') else None
        if type_constraints is not None:
            constraints = type_constraints

    return constraints


#
# ConstraintClause
#

def apply_constraint_to_value(context, presentation, constraint_clause, value): # pylint: disable=too-many-statements,too-many-return-statements,too-many-branches
    """
    Returns false if the value does not conform to the constraint.
    """

    constraint_key = constraint_clause._raw.keys()[0]
    the_type = constraint_clause._get_type(context)
    # PropertyAssignment does not have this:
    entry_schema = getattr(presentation, 'entry_schema', None)

    def coerce_constraint(constraint):
        return coerce_value(context, presentation, the_type, entry_schema, None, constraint,
                            constraint_key)

    def report(message, constraint):
        context.validation.report('value %s %s per constraint in "%s": %s'
                                  % (message, safe_repr(constraint),
                                     presentation._name or presentation._container._name,
                                     safe_repr(value)),
                                  locator=presentation._locator, level=Issue.BETWEEN_FIELDS)

    if constraint_key == 'equal':
        constraint = coerce_constraint(constraint_clause.equal)
        if value != constraint:
            report('is not equal to', constraint)
            return False

    elif constraint_key == 'greater_than':
        constraint = coerce_constraint(constraint_clause.greater_than)
        if value <= constraint:
            report('is not greater than', constraint)
            return False

    elif constraint_key == 'greater_or_equal':
        constraint = coerce_constraint(constraint_clause.greater_or_equal)
        if value < constraint:
            report('is not greater than or equal to', constraint)
            return False

    elif constraint_key == 'less_than':
        constraint = coerce_constraint(constraint_clause.less_than)
        if value >= constraint:
            report('is not less than', constraint)
            return False

    elif constraint_key == 'less_or_equal':
        constraint = coerce_constraint(constraint_clause.less_or_equal)
        if value > constraint:
            report('is not less than or equal to', constraint)
            return False

    elif constraint_key == 'in_range':
        lower, upper = constraint_clause.in_range
        lower, upper = coerce_constraint(lower), coerce_constraint(upper)
        if value < lower:
            report('is not greater than or equal to lower bound', lower)
            return False
        if (upper != 'UNBOUNDED') and (value > upper):
            report('is not lesser than or equal to upper bound', upper)
            return False

    elif constraint_key == 'valid_values':
        constraint = tuple(coerce_constraint(v) for v in constraint_clause.valid_values)
        if value not in constraint:
            report('is not one of', constraint)
            return False

    elif constraint_key == 'length':
        constraint = constraint_clause.length
        try:
            if len(value) != constraint:
                report('is not of length', constraint)
                return False
        except TypeError:
            pass # should be validated elsewhere

    elif constraint_key == 'min_length':
        constraint = constraint_clause.min_length
        try:
            if len(value) < constraint:
                report('has a length lesser than', constraint)
                return False
        except TypeError:
            pass # should be validated elsewhere

    elif constraint_key == 'max_length':
        constraint = constraint_clause.max_length
        try:
            if len(value) > constraint:
                report('has a length greater than', constraint)
                return False
        except TypeError:
            pass # should be validated elsewhere

    elif constraint_key == 'pattern':
        constraint = constraint_clause.pattern
        try:
            # From TOSCA 1.0 3.5.2.1:
            #
            # "Note: Future drafts of this specification will detail the use of regular expressions
            # and reference an appropriate standardized grammar."
            #
            # So we will just use Python's.
            if re.match(constraint, str(value)) is None:
                report('does not match regular expression', constraint)
                return False
        except re.error:
            pass # should be validated elsewhere

    return True


#
# Repository
#

def get_data_type_value(context, presentation, field_name, type_name):
    the_type = get_type_by_full_or_shorthand_name(context, type_name, 'data_types')
    if the_type is not None:
        value = getattr(presentation, field_name)
        if value is not None:
            return coerce_data_type_value(context, presentation, the_type, None, None, value, None)
    else:
        context.validation.report('field "%s" in "%s" refers to unknown data type "%s"'
                                  % (field_name, presentation._fullname, type_name),
                                  locator=presentation._locator, level=Issue.BETWEEN_TYPES)
    return None


#
# Utils
#

PRIMITIVE_DATA_TYPES = {
    # YAML 1.2:
    'tag:yaml.org,2002:str': unicode,
    'tag:yaml.org,2002:integer': int,
    'tag:yaml.org,2002:float': float,
    'tag:yaml.org,2002:bool': bool,
    'tag:yaml.org,2002:null': None.__class__,

    # TOSCA aliases:
    'string': unicode,
    'integer': int,
    'float': float,
    'boolean': bool,
    'null': None.__class__}


@implements_specification('3.2.1-3', 'tosca-simple-1.0')
def get_primitive_data_type(type_name):
    """
    Many of the types we use in this profile are built-in types from the YAML 1.2 specification
    (i.e., those identified by the "tag:yaml.org,2002" version tag) [YAML-1.2].

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #_Toc373867862>`__
    """

    return PRIMITIVE_DATA_TYPES.get(type_name)


def get_data_type_name(the_type):
    """
    Returns the name of the type, whether it's a DataType, a primitive type, or another class.
    """

    return the_type._name if hasattr(the_type, '_name') else full_type_name(the_type)


def coerce_value(context, presentation, the_type, entry_schema, constraints, value, aspect=None): # pylint: disable=too-many-return-statements
    """
    Returns the value after it's coerced to its type, reporting validation errors if it cannot be
    coerced.

    Supports both complex data types and primitives.

    Data types can use the ``coerce_value`` extension to hook their own specialized function.
    If the extension is present, we will delegate to that hook.
    """

    # TODO: should support models as well as presentations

    is_function, func = get_function(context, presentation, value)
    if is_function:
        return func

    if the_type is None:
        return value

    if the_type == None.__class__:
        if value is not None:
            context.validation.report('field "%s" is of type "null" but has a non-null value: %s'
                                      % (presentation._name, safe_repr(value)),
                                      locator=presentation._locator, level=Issue.BETWEEN_FIELDS)
            return None

    # Delegate to 'coerce_value' extension
    if hasattr(the_type, '_get_extension'):
        coerce_value_fn_name = the_type._get_extension('coerce_value')
        if coerce_value_fn_name is not None:
            if value is None:
                return None
            coerce_value_fn = import_fullname(coerce_value_fn_name)
            return coerce_value_fn(context, presentation, the_type, entry_schema, constraints,
                                   value, aspect)

    if hasattr(the_type, '_coerce_value'):
        # Delegate to '_coerce_value' (likely a DataType instance)
        return the_type._coerce_value(context, presentation, entry_schema, constraints, value,
                                      aspect)

    # Coerce to primitive type
    return coerce_to_primitive(context, presentation, the_type, constraints, value, aspect)


def coerce_to_primitive(context, presentation, primitive_type, constraints, value, aspect=None):
    """
    Returns the value after it's coerced to a primitive type, translating exceptions to validation
    errors if it cannot be coerced.
    """

    if value is None:
        return None

    try:
        # Coerce
        value = validate_primitive(value, primitive_type,
                                   context.validation.allow_primitive_coersion)

        # Check constraints
        apply_constraints_to_value(context, presentation, constraints, value)
    except ValueError as e:
        report_issue_for_bad_format(context, presentation, primitive_type, value, aspect, e)
        value = None
    except TypeError as e:
        report_issue_for_bad_format(context, presentation, primitive_type, value, aspect, e)
        value = None

    return value


def coerce_to_data_type_class(context, presentation, cls, entry_schema, constraints, value,
                              aspect=None):
    """
    Returns the value after it's coerced to a data type class, reporting validation errors if it
    cannot be coerced. Constraints will be applied after coersion.

    Will either call a ``_create`` static function in the class, or instantiate it using a
    constructor if ``_create`` is not available.

    This will usually be called by a ``coerce_value`` extension hook in a :class:`DataType`.
    """

    try:
        if hasattr(cls, '_create'):
            # Instantiate using creator function
            value = cls._create(context, presentation, entry_schema, constraints, value, aspect)
        else:
            # Normal instantiation
            value = cls(entry_schema, constraints, value, aspect)
    except ValueError as e:
        report_issue_for_bad_format(context, presentation, cls, value, aspect, e)
        value = None

    # Check constraints
    value = apply_constraints_to_value(context, presentation, constraints, value)

    return value


def apply_constraints_to_value(context, presentation, constraints, value):
    """
    Applies all constraints to the value. If the value conforms, returns the value. If it does not
    conform, returns None.
    """

    if (value is not None) and (constraints is not None):
        valid = True
        for constraint in constraints:
            if not constraint._apply_to_value(context, presentation, value):
                valid = False
        if not valid:
            value = None
    return value


def get_container_data_type(presentation):
    if presentation is None:
        return None
    if type(presentation).__name__ == 'DataType':
        return presentation
    return get_container_data_type(presentation._container)


def report_issue_for_bad_format(context, presentation, the_type, value, aspect, e):
    if aspect == 'default':
        aspect = '"default" value'
    elif aspect is not None:
        aspect = '"%s" aspect' % aspect

    if aspect is not None:
        context.validation.report('%s for field "%s" is not a valid "%s": %s'
                                  % (aspect, presentation._name or presentation._container._name,
                                     get_data_type_name(the_type), safe_repr(value)),
                                  locator=presentation._locator, level=Issue.BETWEEN_FIELDS,
                                  exception=e)
    else:
        context.validation.report('field "%s" is not a valid "%s": %s'
                                  % (presentation._name or presentation._container._name,
                                     get_data_type_name(the_type), safe_repr(value)),
                                  locator=presentation._locator, level=Issue.BETWEEN_FIELDS,
                                  exception=e)
