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

"""
Schema for AMQP management entity types.

Schema validation will validate and transform values, add default values and
check for uniqueness of enties/attributes that are specified to be unique.

A Schema can be loaded/dumped to a json file.
"""

import sys
from qpid_dispatch.management.entity import EntityBase
from qpid_dispatch.management.error import NotImplementedStatus
from ...compat import OrderedDict, JSON_LOAD_KWARGS
import json
from pkgutil import get_data

class ValidationError(Exception):
    """Error raised if schema validation fails"""
    pass

def quotestr(value, quote="'"):
    """Quote value if it is a string type, str() it if not """
    if isinstance(value, basestring): return "'%s'" % value
    else: return str(value)


class Type(object):
    """Base class for schema types.

    @ivar name: The type name.
    @ivar pytype: The python type for this schema type.
    """
    def __init__(self, name, pytype):
        """
        @param name: The type name.
        @param pytype: The python type for this schema type.
        """
        self.name, self.pytype = name, pytype

    def validate(self, value, **kwargs): # pylint: disable=unused-argument
        """
        Convert value to the correct python type.

        @param kwargs: See L{Schema.validate_all}
        """
        return self.pytype(value)

    def dump(self):
        """
        @return: Representation of the type to dump to json. Normally the type name,
            EnumType.dump is the exception.
        """
        return self.name

    def __str__(self):
        """String name of type."""
        return str(self.dump())


class BooleanType(Type):
    """A boolean schema type"""

    def __init__(self):
        super(BooleanType, self).__init__("boolean", bool)

    VALUES = {"yes":1, "true":1, "on":1, "no":0, "false":0, "off":0}

    def validate(self, value, **kwargs):
        """
        @param value: A string such as "yes", "false" etc. is converted appropriately.
            Any other type is converted using python's bool()
        @param kwargs: See L{Schema.validate_all}
        @return A python bool.
        """
        try:
            if isinstance(value, basestring):
                return self.VALUES[value.lower()]
            return bool(value)
        except:
            raise ValidationError("Invalid Boolean value '%r'"%value)


class EnumValue(str):
    """A string that convets to an integer value via int()"""

    def __new__(cls, name, value):
        s = super(EnumValue, cls).__new__(cls, name)
        setattr(s, 'value', value)
        return s

    def __int__(self): return self.value
    def __eq__(self, x): return str(self) == x or int(self) == x
    def __ne__(self, x): return not self == x
    def __repr__(self): return "EnumValue('%s', %s)"%(str(self), int(self))


class EnumType(Type):
    """An enumerated type"""

    def __init__(self, tags):
        """
        @param tags: A list of string values for the enumerated type.
        """
        assert isinstance(tags, list)
        super(EnumType, self).__init__("enum%s"%([str(t) for t in tags]), int)
        self.tags = tags

    def validate(self, value, **kwargs):
        """
        @param value: May be a string from the set of enum tag strings or anything
            that can convert to an int - in which case it must be in the enum range.
        @param kwargs: See L{Schema.validate_all}
        @return: An EnumValue.
        """
        if value in self.tags:
            return self.tags.index(value)
            # return EnumValue(value, self.tags.index(value))
        else:
            try:
                i = int(value)
                return i
            except (ValueError, IndexError):
                pass
        raise ValidationError("Invalid value for %s: %r"%(self.name, value))

    def dump(self):
        """
        @return: A list of the enum tags.
        """
        return self.tags

    def __str__(self):
        """String description of enum type."""
        return "One of [%s]" % ', '.join([quotestr(tag) for tag in self.tags])

BUILTIN_TYPES = OrderedDict(
    (t.name, t) for t in [Type("string", str),
                          Type("path", str),
                          Type("entityId", str),
                          Type("integer", int),
                          Type("list", list),
                          Type("map", dict),
                          Type("dict", dict),
                          BooleanType()])

def get_type(rep):
    """
    Get a schema type.
    @param rep: json representation of the type.
    """
    if isinstance(rep, list):
        return EnumType(rep)
    if rep in BUILTIN_TYPES:
        return BUILTIN_TYPES[rep]
    raise ValidationError("No such schema type: %s" % rep)

def _dump_dict(items):
    """
    Remove all items with None value from a mapping.
    @return: Map of non-None items.
    """
    return OrderedDict((k, v) for k, v in items if v)

def _is_unique(found, item):
    """
    Return true if found is None or item is not in found (adds item to found.)
    Return false if item is in found.
    """
    if found is None or found is False:
        return True
    if item not in found:
        found.add(item)
        return True
    return False

class AttributeType(object):
    """
    Definition of an attribute.

    @ivar name: Attribute name.
    @ivar atype: Attribute L{Type}
    @ivar required: True if the attribute is required.
    @ivar default: Default value for the attribute or None if no default. Can be a reference.
    @ivar value: Fixed value for the attribute. Can be a reference.
    @ivar unique: True if the attribute value is unique.
    @ivar description: Description of the attribute type.
    @ivar defined_in: EntityType in which this attribute is defined.
    @ivar create: If true the attribute can be set by CREATE.
    @ivar update: If true the attribute can be modified by UPDATE.
    @ivar graph: If true the attribute could be graphed by a console.
    """

    def __init__(self, name, type=None, defined_in=None, default=None,
                 required=False, unique=False, hidden=False, deprecated=False,
                 value=None, description="", create=False, update=False, graph=False, ordinality=0):
        """
        See L{AttributeType} instance variables.
        """
        try:
            self.name = name
            self.type = type
            self.defined_in = defined_in
            self.atype = get_type(self.type)
            self.required = required
            self.hidden = hidden
            self.deprecated = deprecated
            self.default = default
            self.value = value
            self.unique = unique
            self.description = description
            self.ordinality = ordinality
            if self.value is not None and self.default is not None:
                raise ValidationError("Attribute '%s' has default value and fixed value" %
                                      self.name)
            self.create=create
            self.update=update
            self.graph=graph
        except:
            ex, msg, trace = sys.exc_info()
            raise ValidationError, "Attribute '%s': %s" % (name, msg), trace

    def missing_value(self, check_required=True, add_default=True, **kwargs):
        """
        Fill in missing default and fixed values.
        @keyword check_required: Raise an exception if required attributes are misssing.
        @keyword add_default:  Add a default value for missing attributes.
        @param kwargs: See L{Schema.validate_all}
        """
        if self.value is not None: # Fixed value attribute
            return self.value
        if add_default and self.default is not None:
            return self.default
        if check_required and self.required:
            raise ValidationError("Missing required attribute '%s'" % (self.name))

    def validate(self, value, check_unique=None, **kwargs):
        """
        Validate value for this attribute definition.
        @param value: The value to validate.
        @keyword check_unique: set of (name, value) to check for attribute uniqueness.
            None means don't check for uniqueness.
        @param create: if true, check that the attribute allows create
        @param update: if true, check that the attribute allows update
        @param kwargs: See L{Schema.validate_all}
        @return: value converted to the correct python type. Rais exception if any check fails.
        """
        if self.unique and not _is_unique(check_unique, (self.name, value)):
            raise ValidationError("Duplicate value '%s' for unique attribute '%s'"%(value, self.name))
        if self.value and value != self.value:
            raise ValidationError("Attribute '%s' has fixed value '%s' but given '%s'"%(
                self.name, self.value, value))
        try:
            return self.atype.validate(value, **kwargs)
        except (TypeError, ValueError), e:
            raise ValidationError, str(e), sys.exc_info()[2]

    def dump(self):
        """
        @return: Json-friendly representation of an attribute type
        """
        return _dump_dict([
            ('type', self.atype.dump()),
            ('default', self.default),
            ('required', self.required),
            ('unique', self.unique),
            ('deprecated', self.deprecated),
            ('description', self.description),
            ('graph', self.graph)
        ])

    def __str__(self):
        return self.name


class MessageDef(object):
    """A request or response message"""
    def __init__(self, body=None, properties=None):
        self.body = None
        if body: self.body = AttributeType("body", **body)
        self.properties = dict((name, AttributeType(name, **value))
                               for name, value in (properties or {}).iteritems())


class OperationDef(object):
    """An operation definition"""
    def __init__(self, name, description=None, request=None, response=None, ordinality=None):
        try:
            self.name = name
            self.description = description
            self.ordinality = ordinality
            self.request = self.response = None
            if request:
                self.request = MessageDef(**request)
            if response:
                self.response = MessageDef(**response)
        except:
            ex, msg, trace = sys.exc_info()
            raise ValidationError, "Operation '%s': %s" % (name, msg), trace


class EntityType(object):
    """
    An entity type defines a set of attributes for an entity.

    @ivar name: Fully qualified entity type name.
    @ivar short_name: Un-prefixed short name.
    @ivar attributes: Map of L{AttributeType} for entity.
    @ivar singleton: If true only one entity of this type is allowed.
    @ivar referential: True if an entity can be referred to by name from another entity.
    """
    def __init__(self, name, schema, attributes=None, operations=None, operationDefs=None, description="",
                 fullName=True, singleton=False, deprecated=False, extends=None, referential=False, ordinality=0, **kwargs):
        """
        @param name: name of the entity type.
        @param schema: schema for this type.
        @param singleton: True if entity type is a singleton.
        @param attributes: Map of attributes {name: {type:, default:, required:, unique:}}
        @param description: Human readable description.
        @param operations: Allowed operations, list of operation names.
        """
        try:
            self.schema = schema
            self.description = description
            if fullName:
                self.name = schema.long_name(name)
                self.short_name = schema.short_name(name)

                if self.short_name.startswith("router.config."):
                    self.short_name = self.short_name.replace("router.config.", "")
            else:
                self.name = self.short_name = name

            self.attributes = OrderedDict((k, AttributeType(k, defined_in=self, **v))
                                          for k, v in (attributes or {}).iteritems())
            self.operations = operations or []
            # Bases are resolved in self.init()
            self.base = extends
            self.all_bases = []

            self.references = []
            self.singleton = singleton
            self.deprecated = deprecated
            self.referential = referential
            self.ordinality = ordinality
            self._init = False      # Have not yet initialized from base and attributes.
            # Operation definitions
            self.operation_defs = dict((name, OperationDef(name, **op))
                                  for name, op in (operationDefs or {}).iteritems())
        except:
            ex, msg, trace = sys.exc_info()
            raise ValidationError, "%s '%s': %s" % (type(self).__name__, name, msg), trace

    def init(self):
        """Find bases after all types are loaded."""
        if self._init: return
        self._init = True
        if self.base:
            self.base = self.schema.entity_type(self.base)
            self.base.init()
            self.all_bases = [self.base] + self.base.all_bases
            self._extend(self.base, 'extend')

    def _extend(self, other, how):
        """Add attributes and operations from other"""
        def check(a, b, what):
            overlap = set(a) & set(b)
            if overlap:
                raise ValidationError("'%s' cannot %s '%s', re-defines %s: %s"
                                      % (self.name, how, other.short_name, what, ",".join(overlap)))
        check(self.operations, other.operations, "operations")
        self.operations += other.operations
        check(self.attributes.iterkeys(), other.attributes.itervalues(), "attributes")
        self.attributes.update(other.attributes)

        if other.name == 'entity':
            # Fill in entity "type" attribute automatically.
            self.attributes["type"]["value"] = self.name

        ordinality = 0
        for attrib in self.attributes.values():
            attrib.ordinality = ordinality
            ordinality += 1

    def extends(self, base):
        return base in self.all_bases

    def is_a(self, type):
        return type == self or self.extends(type)

    def attribute(self, name):
        """Get the AttributeType for name"""
        if not name in self.attributes:
            raise ValidationError("Unknown attribute '%s' for '%s'" % (name, self))
        return self.attributes[name]

    @property
    def my_attributes(self):
        """Return only attribute types defined in this entity type"""
        return [a for a in self.attributes.itervalues() if a.defined_in == self]

    def validate(self, attributes, check_singleton=None, **kwargs):
        """
        Validate attributes for entity type.
        @param attributes: Map attributes name:value or Entity with attributes property.
            Modifies attributes: adds defaults, converts values.
        @param check_singleton: set of entity-type name to enable singleton checking.
            None to disable.
        @param kwargs: See L{Schema.validate_all}
        """

        if isinstance(attributes, SchemaEntity): attributes = attributes.attributes

        if self.singleton and not _is_unique(check_singleton, self.name):
            raise ValidationError("Multiple instances of singleton '%s'"%self.name)
        try:
            # Add missing values
            for attr in self.attributes.itervalues():
                if attributes.get(attr.name) is None:
                    value = attr.missing_value(**kwargs)
                    if value is not None: attributes[attr.name] = value
                    if value is None and attr.name in attributes:
                        del attributes[attr.name]

            # Validate attributes.
            for name, value in attributes.iteritems():
                if name == 'type':
                    value = self.schema.long_name(value)
                attributes[name] = self.attribute(name).validate(value, **kwargs)
        except ValidationError, e:
            raise  ValidationError, "%s: %s"%(self, e), sys.exc_info()[2]

        return attributes

    def allowed(self, op):
        """Raise exception if op is not a valid operation on entity."""
        op = op.upper()
        if not op in self.operations:
            raise NotImplementedStatus("Operation '%s' not implemented for '%s' %s" % (
                op, self.name, self.operations))

    def create_check(self, attributes):
        for a in attributes:
            if not self.attribute(a).create:
                raise ValidationError("Cannot set attribute '%s' in CREATE" % a)

    def update_check(self, new_attributes, old_attributes):
        for a, v in new_attributes.iteritems():
            # Its not an error to include an attribute in UPDATE if the value is not changed.
            if not self.attribute(a).update and \
               not (a in old_attributes and old_attributes[a] == v):
                raise ValidationError("Cannot update attribute '%s' in UPDATE" % a)

    def dump(self):
        """Json friendly representation"""
        return _dump_dict([
            ('attributes', OrderedDict(
                (k, v.dump()) for k, v in self.attributes.iteritems()
                if k != 'type')), # Don't dump 'type' attribute, dumped separately.
            ('operations', self.operations),
            ('description', self.description or None),
            ('fullyQualifiedType', self.name or None),
            ('references', self.references),
            ('deprecated', self.deprecated),
            ('singleton', self.singleton)
        ])

    def __repr__(self):
        return "%s(%s)" % (type(self).__name__, self.name)

    def __str__(self):
        return self.name

    def name_is(self, name):
        return self.name == self.schema.long_name(name)



class Schema(object):
    """
    Schema defining entity types.
    Note: keyword arguments come from schema so use camelCase

    @ivar prefix: Prefix to prepend to short entity type names.
    @ivar entityTypes: Map of L{EntityType} by name.
    @ivar description: Text description of schema.
    """
    def __init__(self, prefix="", entityTypes=None, description=""):
        """
        @param prefix: Prefix for entity names.
        @param entity_types: Map of  { entityTypeName: { singleton:, attributes:{...}}}
        @param description: Human readable description.
        """
        if prefix:
            self.prefix = prefix.strip('.')
            self.prefixdot = self.prefix + '.'
        else:
            self.prefix = self.prefixdot = ""
        self.description = description

        def parsedefs(cls, defs):
            return OrderedDict((self.long_name(k), cls(k, self, **v))
                               for k, v in (defs or {}).iteritems())

        self.entity_types = parsedefs(EntityType, entityTypes)

        self.all_attributes = set()

        ordinality = 0
        operation_def_ordinality = 0
        self.all_operation_defs = OrderedDict()
        for e in self.entity_types.itervalues():
            e.init()
            e.ordinality = ordinality
            for key in e.operation_defs:
                op_def = e.operation_defs[key]
                op_def.ordinality = operation_def_ordinality
                operation_def_ordinality += 1
                self.all_operation_defs[key] = op_def
            self.all_attributes.update(e.attributes.keys())
            ordinality += 1

    def short_name(self, name):
        """Remove prefix from name if present"""
        if not name:
            return name
        if name.startswith(self.prefixdot):
            name = name[len(self.prefixdot):]
        return name

    def long_name(self, name):
        """Add prefix to unqualified name"""
        if not name:
            return name
        if not name.startswith(self.prefixdot):
            name = self.prefixdot + name
        return name

    def is_long_name(self, name):
        if not name:
            return False
        if self.prefixdot in name:
            return True
        return False

    def dump(self):
        """Return json-friendly representation"""
        return OrderedDict([
            ('prefix', self.prefix),
            ('entityTypes',
             OrderedDict((e.short_name, e.dump()) for e in self.entity_types.itervalues()))
        ])

    def _lookup(self, map, name, message, error):
        found = map.get(name) or map.get(self.long_name(name))
        if not found and error:
            raise ValidationError(message % name)
        return found

    def entity_type(self, name, error=True):
        return self._lookup(self.entity_types, name, "No such entity type '%s'", error)

    def validate_entity(self, attributes, check_required=True, add_default=True,
                        check_unique=None, check_singleton=None):
        """
        Validate a single entity.

        @param attributes: Map of attribute name: value
        @keyword check_required: Raise exception if required attributes are missing.
        @keyword add_default: Add defaults for missing attributes.
        @keyword check_unique: Used by L{validate_all}
        @keyword check_singleton: Used by L{validate_all}
        """
        attributes['type'] = self.long_name(attributes['type'])
        entity_type = self.entity_type(attributes['type'])
        entity_type.validate(
            attributes,
            check_required=check_required,
            add_default=add_default,
            check_unique=check_unique,
            check_singleton=check_singleton)

    def validate_all(self, attribute_maps, check_required=True, add_default=True,
                     check_unique=True, check_singleton=True):
        """
        Validate a list of attribute maps representing entity attributes.
        Verify singleton entities and unique attributes are unique.
        Modifies attribute_maps, adds default values, converts values.

        @param attribute_maps: List of attribute name:value maps.
        @keyword check_required: Raise exception if required attributes are missing.
        @keyword add_default: Add defaults for missing attributes.
        @keyword check_unique: Raise exception if unique attributes are duplicated.
        @keyword check_singleton: Raise exception if singleton entities are duplicated
        """
        if check_singleton: check_singleton = set()
        if check_unique: check_unique = set()

        for e in attribute_maps:
            self.validate_entity(e,
                                 check_required=check_required,
                                 add_default=add_default,
                                 check_unique=check_unique,
                                 check_singleton=check_singleton)

    def entity(self, attributes):
        """Convert an attribute map into an L{SchemaEntity}"""
        attributes = dict((k, v) for k, v in attributes.iteritems() if v is not None)
        return SchemaEntity(self.entity_type(attributes['type']), attributes)

    def entities(self, attribute_maps):
        """Convert a list of attribute maps into a list of L{SchemaEntity}"""
        return [self.entity(m) for m in attribute_maps]

    def filter(self, predicate):
        """Return an iterator over entity types that satisfy predicate."""
        if predicate is None: return self.entity_types.itervalues()
        return (t for t in self.entity_types.itervalues() if predicate(t))

    def by_type(self, type):
        """Return an iterator over entity types that extend or are type.
        If type is None return all entities."""
        if not type:
            return self.entity_types.itervalues()
        else:
            return self.filter(lambda t: t.is_a(type))


class QdSchema(Schema):
    """
    Qpid Dispatch Router management schema.
    """

    CONFIGURATION_ENTITY = u"configurationEntity"
    OPERATIONAL_ENTITY = u"operationalEntity"

    def __init__(self):
        """Load schema."""
        qd_schema = get_data('qpid_dispatch.management', 'qdrouter.json')
        try:
            super(QdSchema, self).__init__(**json.loads(qd_schema, **JSON_LOAD_KWARGS))
        except Exception,e:
            raise ValueError("Invalid schema qdrouter.json: %s" % e)
        self.configuration_entity = self.entity_type(self.CONFIGURATION_ENTITY)
        self.operational_entity = self.entity_type(self.OPERATIONAL_ENTITY)

    def validate_full(self, entities, **kwargs):
        """
        In addition to L{schema.Schema.validate}, check the following:

        listeners and connectors can only have role=inter-router if the
        router has mode=interior.


        @param entities: List of attribute name:value maps.
        @param kwargs: See L{schema.Schema.validate}
        """
        entities = list(entities) # Need to traverse twice
        super(QdSchema, self).validate_all(entities, **kwargs)
        inter_router = not_interior = None
        for e in entities:
            if self.short_name(e.type) == "router" and e.mode != "interior":
                not_interior = e.mode
            if self.short_name(e.type) in ["listener", "connector"] and e.role == "inter-router":
                inter_router = e
            if not_interior and inter_router:
                raise ValidationError(
                    "role='inter-router' only allowed with router mode='interior' for %s." % inter_router)

    def is_configuration(self, entity_type):
        return entity_type and self.configuration_entity in entity_type.all_bases

    def is_operational(self, entity_type):
        return entity_type and self.operational_entity in entity_type.all_bases


class SchemaEntity(EntityBase):
    """A map of attributes associated with an L{EntityType}"""
    def __init__(self, entity_type, attributes=None, validate=True, **kwattrs):
        super(SchemaEntity, self).__init__(attributes, **kwattrs)
        self.__dict__['entity_type'] = entity_type
        self.attributes.setdefault('type', entity_type.name)
        if validate: self.validate()

    def _set(self, name, value):
        super(SchemaEntity, self)._set(name, value)
        self.validate()

    def validate(self, **kwargs):
        self.entity_type.validate(self.attributes, **kwargs)
