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

from .specification import implements_specification


BASE_TYPES_TO_CANONICAL_NAMES = {
    # TOSCA aliases:
    None.__class__: 'null',
    basestring: 'string',
    int: 'integer',
    float: 'float',
    bool: 'boolean',
    list: 'list',
    tuple: 'list',
    dict: 'map',
    datetime.datetime: 'timestamp'
}

NAMES_TO_CANONICAL_TYPES = {
    # Python:
    'none': None.__class__,
    'basestring': unicode,
    'str': unicode,
    'unicode': unicode,
    'int': int,
    'float': float, # also a TOSCA alias
    'bool': bool,
    'list': list, # also a TOSCA alias
    'tuple': list,
    'dict': dict,
    'datetime': datetime.datetime,

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

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

    # TOSCA custom types:
    'map': dict,
    'timestamp': datetime.datetime
}


def full_type_name(value):
    """
    The full class name of a type or instance.
    """

    if not isinstance(value, type):
        value = value.__class__
    module = str(value.__module__)
    name = str(value.__name__)
    return name if module == '__builtin__' else '{0}.{1}'.format(module, name)


@implements_specification('3.2.1-1', 'tosca-simple-1.0')
def canonical_type_name(value):
    """
    Returns the canonical TOSCA type name of a primitive value, or None if unknown.

    For a list of TOSCA type names, 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>`__
    """

    for the_type, name in BASE_TYPES_TO_CANONICAL_NAMES.iteritems():
        if isinstance(value, the_type):
            return name
    return None


@implements_specification('3.2.1-2', 'tosca-simple-1.0')
def canonical_type(type_name):
    """
    Return the canonical type for any Python, YAML, or TOSCA type name or alias, or None if
    unsupported.

    :param type_name: Type name (case insensitive)
    """

    return NAMES_TO_CANONICAL_TYPES.get(type_name.lower())


def validate_value_type(value, type_name):
    """
    Validate that a value is of a specific type. Supports Python, YAML, and TOSCA type names and
    aliases.

    A ValueError will be raised on type mismatch.

    :param type_name: Type name (case insensitive)
    """

    the_type = canonical_type(type_name)
    if the_type is None:
        raise RuntimeError('Unsupported type name: {0}'.format(type_name))

    # The following Python types do not inherit from the canonical type, but are considered valid
    if (the_type is unicode) and isinstance(value, str):
        return
    if (the_type is list) and isinstance(value, tuple):
        return

    if not isinstance(value, the_type):
        raise ValueError('Value {0} is not of type {1}'.format(value, type_name))


def convert_value_to_type(str_value, python_type_name):
    """
    Converts a value to a specific Python primitive type.

    A ValueError will be raised for unsupported types or conversion failure.

    :param python_type_name: Python primitive type name (case insensitive)
    """

    python_type_name = python_type_name.lower()
    try:
        if python_type_name in ('str', 'unicode'):
            return str_value.decode('utf-8')
        elif python_type_name == 'int':
            return int(str_value)
        elif python_type_name == 'bool':
            return bool(str_value)
        elif python_type_name == 'float':
            return float(str_value)
        else:
            raise ValueError('Unsupported Python type name: {0}'.format(python_type_name))
    except ValueError:
        raise ValueError('Failed to to convert {0} to {1}'.format(str_value,
                                                                  python_type_name))
