# -*- coding: utf-8 -*-
#
# Copyright (c) 2015, Alcatel-Lucent Inc
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the copyright holder nor the names of its contributors
#       may be used to endorse or promote products derived from this software without
#       specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import unicode_literals
from builtins import object

from monolithe.lib import SDKUtils


class SpecificationAttribute(object):
    """ Define an attribute of an object

    """
    def __init__(self, specification=None, data=None):
        """ Define an attribute

            Example:
                name: associatedGatewayID
                local_name: associated_gateway_id
                local_type: str
        """
        # Main attributes
        self.description = None
        self.local_name = None
        self.local_type = None

        # Other attributes
        self._name = None
        self.channel = None
        self.allowed_chars = None
        self.allowed_choices = None
        self.autogenerated = False
        self.availability = None
        self.creation_only = False
        self.default_order = False
        self.default_value = None
        self.deprecated = False
        self.filterable = False
        self.format = "free"
        self.max_length = None
        self.max_value = None
        self.min_length = None
        self.min_value = None
        self.orderable = False
        self.read_only = False
        self.required = False
        self.unique = False
        self.unique_scope = None
        self._type = None
        self.exposed = False
        self.transient = False
        self.subtype = None
        self.userlabel = None

        self.specification = specification
        # Load information from data
        if data:
            self.from_dict(data)

    @property
    def type(self):
        """
        """
        return self._type

    @type.setter
    def type(self, value):
        """
        """
        language = self.specification.monolithe_config.language if self.specification and self.specification.monolithe_config else 'python'

        self._type = SDKUtils.massage_type_name(type_name=value)
        self.local_type = SDKUtils.get_type_name_in_language(type_name=value, sub_type=self.subtype, language=language)

    @property
    def name(self):
        """
        """
        return self._name

    @name.setter
    def name(self, value):
        """
        """
        self._name = value

        language = self.specification.monolithe_config.language if self.specification and self.specification.monolithe_config else 'python'

        if self.specification and self.specification.monolithe_config:
            self.local_name = SDKUtils.get_idiomatic_name_in_language(name=self.specification.monolithe_config.map_attribute(self.specification.rest_name, value), language=language)
        else:
            self.local_name = SDKUtils.get_idiomatic_name_in_language(name=value, language=language)

    def from_dict(self, data):
        """

        """
        try:
            # this must be done before setting the type
            self.subtype = data["subtype"] if "subtype" in data else None

            # mandatory characteristics
            self.name = data["name"]
            self.description = data["description"]
            self.type = data["type"]

            # optional characteristics
            self.allowed_chars = data["allowed_chars"] if "allowed_chars" in data else None
            self.allowed_choices = data["allowed_choices"] if "allowed_choices" in data else None
            self.autogenerated = data["autogenerated"] if "autogenerated" in data else False
            self.channel = data["channel"] if "channel" in data else None
            self.creation_only = data["creation_only"] if "creation_only" in data else False
            self.default_order = data["default_order"] if "default_order" in data else False
            self.default_value = data["default_value"] if "default_value" in data else None
            self.deprecated = data["deprecated"] if "deprecated" in data else False
            self.exposed = data["exposed"] if "exposed" in data else False
            self.filterable = data["filterable"] if "filterable" in data else False
            self.format = data["format"] if "format" in data else "free"
            self.max_length = data["max_length"] if "max_length" in data else None
            self.max_value = data["max_value"] if "max_value" in data else None
            self.min_length = data["min_length"] if "min_length" in data else None
            self.min_value = data["min_value"] if "min_value" in data else None
            self.orderable = data["orderable"] if "orderable" in data else False
            self.read_only = data["read_only"] if "read_only" in data else False
            self.required = data["required"] if "required" in data else False
            self.transient = data["transient"] if "transient" in data else False
            self.unique = data["unique"] if "unique" in data else False
            self.unique_scope = data["unique_scope"] if "unique_scope" in data else None
            self.userlabel = data["userlabel"] if "userlabel" in data else None

        except Exception as ex:
            raise Exception("Unable to parse attribute %s for specification %s: %s" % (self.name, self.specification.rest_name, ex))

    def to_dict(self):
        """ Transform an attribute to a dict
        """
        data = {}

        # mandatory characteristics
        data["name"] = self.name
        data["description"] = self.description if self.description and len(self.description) else None
        data["type"] = self.type if self.type and len(self.type) else None
        data["allowed_chars"] = self.allowed_chars if self.allowed_chars and len(self.allowed_chars) else None
        data["allowed_choices"] = self.allowed_choices
        data["autogenerated"] = self.autogenerated
        data["channel"] = self.channel if self.channel and len(self.channel) else None
        data["creation_only"] = self.creation_only
        data["default_order"] = self.default_order
        data["default_value"] = self.default_value if self.default_value and len(self.default_value) else None
        data["deprecated"] = self.deprecated
        data["exposed"] = self.exposed
        data["filterable"] = self.filterable
        data["format"] = self.format if self.format and len(self.format) else None
        data["max_length"] = int(self.max_length) if self.max_length is not None else None
        data["max_value"] = int(self.max_value) if self.max_value is not None else None
        data["min_length"] = int(self.min_length) if self.min_length is not None else None
        data["min_value"] = int(self.min_value) if self.min_value is not None else None
        data["orderable"] = self.orderable
        data["read_only"] = self.read_only
        data["required"] = self.required
        data["transient"] = self.transient
        data["unique"] = self.unique
        data["uniqueScope"] = self.unique_scope if self.unique_scope and len(self.unique_scope) else None
        data["subtype"] = self.subtype if self.subtype and len(self.subtype) else None
        data["userlabel"] = self.userlabel if self.userlabel and len(self.userlabel) else None

        return data
