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

"""
AMQP Management Entity
"""

import itertools
import re


def clean_dict(items, **kwargs):
    """
    @param items: A mapping or iterable of pairs.
    @return: dict containing items + kwargs without any None values. All keys are unicode.
    """
    if isinstance(items, dict):
        items = items.items()
    return dict((k, v)
                for k, v in itertools.chain(items, kwargs.items())
                if v is not None)


class EntityBase(object):
    """
    A collection of named attributes.

    Attribute access:
    - via index operator: entity['foo']
    - as python attributes: entity.foo (only if attribute name is a legal python identifier
      after replacing '-' with '_')

    @ivar attributes: Map of attribute values for this entity.

    NOTE: EntityBase does not itself implement the python map protocol because map
    methods (in particular 'update') can clash with AMQP methods and attributes.
    """

    def __init__(self, attributes=None, **kwargs):
        self.__dict__['attributes'] = {}
        if attributes:
            for k, v in attributes.items():
                self.attributes[k] = v
                self.__dict__[self._pyname(k)] = v
        for k, v in kwargs.items():
            self._set(k, v)

    def __getitem__(self, name):
        return self.attributes[name]

    def __getattr__(self, name):
        if name in self.attributes:
            return self.attributes[name]
        raise AttributeError

    def __contains__(self, name):
        return name in self.attributes

    @staticmethod
    def _pyname(name): return name.replace('-', '_')

    def _set(self, name, value):
        """Subclasses can override _set to do validation on each change"""
        self.attributes[name] = value
        self.__dict__[self._pyname(name)] = value

    # Access using []
    def __setitem__(self, name, value): self._set(name, value)

    def __delitem__(self, name):
        del self.attributes[name]
        del self.__dict__[self._pyname(name)]

    # Access as python attribute.
    def __setattr__(self, name, value): self._set(name, value)

    def __delattr__(self, name):
        self.__delitem__(name)

    def __repr__(self): return "EntityBase(%r)" % self.attributes

    # attributes name, identity and type are special snowflake
    # attributes that we print before all the not so special
    # attributes.  Assign each a priority for the sort
    _SPECIAL = {"name": 0, "identity": 1, "type": 2}

    def __str__(self):
        # Sort so the _SPECIAL attributes are printed first, 3 ==
        # lower priority than special
        keys = sorted(self.attributes.keys(),
                      key=lambda k: self._SPECIAL.get(k, 3))
        return "Entity(%s)" % ", ".join("%s=%s" % (k, self.attributes[k]) for k in keys)


def update(entity, values):
    """Update entity from values
    @param entity: an Entity
    @param values: a map of values
    """
    for k, v in values.items():
        entity[k] = v


SEPARATOR_RE = re.compile(r' |_|-|\.')


def camelcase(str, capital=False):
    """Convert string str with ' ', '_', '.' or '-' separators to camelCase."""
    if not str:
        return ''
    words = SEPARATOR_RE.split(str)
    first = words[0]
    if capital:
        first = first[0].upper() + first[1:]
    return first + ''.join([w.capitalize() for w in words[1:]])


CAPS_RE = re.compile('[A-Z]')


def uncamelcase(str, separator='_'):
    """Convert camelCase string str to string with separator, e.g. camel_case"""
    if len(str) == 0:
        return str
    return str[0] + CAPS_RE.sub(lambda m: separator + m.group(0).lower(), str[1:])
