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

"""
ARIA modeling service common module
"""

# pylint: disable=no-self-argument, no-member, abstract-method

from sqlalchemy import (
    Column,
    Text,
)
from sqlalchemy.ext.declarative import declared_attr

from ..parser.consumption import ConsumptionContext
from ..utils import (
    collections,
    formatting,
    console,
)
from .mixins import InstanceModelMixin, TemplateModelMixin, ParameterMixin
from . import relationship


class OutputBase(ParameterMixin):
    """
    Output parameter or declaration for an output parameter.
    """

    __tablename__ = 'output'

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        """
        Containing service template (can be ``None``).

        :type: :class:`ServiceTemplate`
        """
        return relationship.many_to_one(cls, 'service_template')

    @declared_attr
    def service(cls):
        """
        Containing service (can be ``None``).

        :type: :class:`ServiceTemplate`
        """
        return relationship.many_to_one(cls, 'service')

    # endregion

    # region foreign keys

    @declared_attr
    def service_template_fk(cls):
        return relationship.foreign_key('service_template', nullable=True)

    @declared_attr
    def service_fk(cls):
        return relationship.foreign_key('service', nullable=True)

    # endregion


class InputBase(ParameterMixin):
    """
    Input parameter or declaration for an input parameter.
    """

    __tablename__ = 'input'

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        """
        Containing service template (can be ``None``).

        :type: :class:`ServiceTemplate`
        """
        return relationship.many_to_one(cls, 'service_template')

    @declared_attr
    def service(cls):
        """
        Containing service (can be ``None``).

        :type: :class:`Service`
        """
        return relationship.many_to_one(cls, 'service')

    @declared_attr
    def interface(cls):
        """
        Containing interface (can be ``None``).

        :type: :class:`Interface`
        """
        return relationship.many_to_one(cls, 'interface')

    @declared_attr
    def operation(cls):
        """
        Containing operation (can be ``None``).

        :type: :class:`Operation`
        """
        return relationship.many_to_one(cls, 'operation')

    @declared_attr
    def interface_template(cls):
        """
        Containing interface template (can be ``None``).

        :type: :class:`InterfaceTemplate`
        """
        return relationship.many_to_one(cls, 'interface_template')

    @declared_attr
    def operation_template(cls):
        """
        Containing operation template (can be ``None``).

        :type: :class:`OperationTemplate`
        """
        return relationship.many_to_one(cls, 'operation_template')

    @declared_attr
    def execution(cls):
        """
        Containing execution (can be ``None``).

        :type: :class:`Execution`
        """
        return relationship.many_to_one(cls, 'execution')

    # endregion

    # region foreign keys

    @declared_attr
    def service_template_fk(cls):
        return relationship.foreign_key('service_template', nullable=True)

    @declared_attr
    def service_fk(cls):
        return relationship.foreign_key('service', nullable=True)

    @declared_attr
    def interface_fk(cls):
        return relationship.foreign_key('interface', nullable=True)

    @declared_attr
    def operation_fk(cls):
        return relationship.foreign_key('operation', nullable=True)

    @declared_attr
    def interface_template_fk(cls):
        return relationship.foreign_key('interface_template', nullable=True)

    @declared_attr
    def operation_template_fk(cls):
        return relationship.foreign_key('operation_template', nullable=True)

    @declared_attr
    def execution_fk(cls):
        return relationship.foreign_key('execution', nullable=True)

    @declared_attr
    def task_fk(cls):
        return relationship.foreign_key('task', nullable=True)

    # endregion


class ConfigurationBase(ParameterMixin):
    """
    Configuration parameter.
    """

    __tablename__ = 'configuration'

    # region many_to_one relationships

    @declared_attr
    def operation_template(cls):
        """
        Containing operation template (can be ``None``).

        :type: :class:`OperationTemplate`
        """
        return relationship.many_to_one(cls, 'operation_template')

    @declared_attr
    def operation(cls):
        """
        Containing operation (can be ``None``).

        :type: :class:`Operation`
        """
        return relationship.many_to_one(cls, 'operation')

    # endregion

    # region foreign keys

    @declared_attr
    def operation_template_fk(cls):
        return relationship.foreign_key('operation_template', nullable=True)

    @declared_attr
    def operation_fk(cls):
        return relationship.foreign_key('operation', nullable=True)

    # endregion


class PropertyBase(ParameterMixin):
    """
    Property parameter or declaration for a property parameter.
    """

    __tablename__ = 'property'

    # region many_to_one relationships

    @declared_attr
    def node_template(cls):
        """
        Containing node template (can be ``None``).

        :type: :class:`NodeTemplate`
        """
        return relationship.many_to_one(cls, 'node_template')

    @declared_attr
    def group_template(cls):
        """
        Containing group template (can be ``None``).

        :type: :class:`GroupTemplate`
        """
        return relationship.many_to_one(cls, 'group_template')

    @declared_attr
    def policy_template(cls):
        """
        Containing policy template (can be ``None``).

        :type: :class:`PolicyTemplate`
        """
        return relationship.many_to_one(cls, 'policy_template')

    @declared_attr
    def relationship_template(cls):
        """
        Containing relationship template (can be ``None``).

        :type: :class:`RelationshipTemplate`
        """
        return relationship.many_to_one(cls, 'relationship_template')

    @declared_attr
    def capability_template(cls):
        """
        Containing capability template (can be ``None``).

        :type: :class:`CapabilityTemplate`
        """
        return relationship.many_to_one(cls, 'capability_template')

    @declared_attr
    def artifact_template(cls):
        """
        Containing artifact template (can be ``None``).

        :type: :class:`ArtifactTemplate`
        """
        return relationship.many_to_one(cls, 'artifact_template')

    @declared_attr
    def node(cls):
        """
        Containing node (can be ``None``).

        :type: :class:`Node`
        """
        return relationship.many_to_one(cls, 'node')

    @declared_attr
    def group(cls):
        """
        Containing group (can be ``None``).

        :type: :class:`Group`
        """
        return relationship.many_to_one(cls, 'group')

    @declared_attr
    def policy(cls):
        """
        Containing policy (can be ``None``).

        :type: :class:`Policy`
        """
        return relationship.many_to_one(cls, 'policy')

    @declared_attr
    def relationship(cls):
        """
        Containing relationship (can be ``None``).

        :type: :class:`Relationship`
        """
        return relationship.many_to_one(cls, 'relationship')

    @declared_attr
    def capability(cls):
        """
        Containing capability (can be ``None``).

        :type: :class:`Capability`
        """
        return relationship.many_to_one(cls, 'capability')

    @declared_attr
    def artifact(cls):
        """
        Containing artifact (can be ``None``).

        :type: :class:`Artifact`
        """
        return relationship.many_to_one(cls, 'artifact')

    # endregion

    # region foreign keys

    @declared_attr
    def node_template_fk(cls):
        return relationship.foreign_key('node_template', nullable=True)

    @declared_attr
    def group_template_fk(cls):
        return relationship.foreign_key('group_template', nullable=True)

    @declared_attr
    def policy_template_fk(cls):
        return relationship.foreign_key('policy_template', nullable=True)

    @declared_attr
    def relationship_template_fk(cls):
        return relationship.foreign_key('relationship_template', nullable=True)

    @declared_attr
    def capability_template_fk(cls):
        return relationship.foreign_key('capability_template', nullable=True)

    @declared_attr
    def artifact_template_fk(cls):
        return relationship.foreign_key('artifact_template', nullable=True)

    @declared_attr
    def node_fk(cls):
        return relationship.foreign_key('node', nullable=True)

    @declared_attr
    def group_fk(cls):
        return relationship.foreign_key('group', nullable=True)

    @declared_attr
    def policy_fk(cls):
        return relationship.foreign_key('policy', nullable=True)

    @declared_attr
    def relationship_fk(cls):
        return relationship.foreign_key('relationship', nullable=True)

    @declared_attr
    def capability_fk(cls):
        return relationship.foreign_key('capability', nullable=True)

    @declared_attr
    def artifact_fk(cls):
        return relationship.foreign_key('artifact', nullable=True)

    # endregion


class AttributeBase(ParameterMixin):
    """
    Attribute parameter or declaration for an attribute parameter.
    """

    __tablename__ = 'attribute'

    # region many_to_one relationships

    @declared_attr
    def node_template(cls):
        """
        Containing node template (can be ``None``).

        :type: :class:`NodeTemplate`
        """
        return relationship.many_to_one(cls, 'node_template')

    @declared_attr
    def node(cls):
        """
        Containing node (can be ``None``).

        :type: :class:`Node`
        """
        return relationship.many_to_one(cls, 'node')

    # endregion

    # region foreign keys

    @declared_attr
    def node_template_fk(cls):
        """For Attribute many-to-one to NodeTemplate"""
        return relationship.foreign_key('node_template', nullable=True)

    @declared_attr
    def node_fk(cls):
        """For Attribute many-to-one to Node"""
        return relationship.foreign_key('node', nullable=True)

    # endregion


class TypeBase(InstanceModelMixin):
    """
    Type and its children. Can serve as the root for a type hierarchy.
    """

    __tablename__ = 'type'

    __private_fields__ = ('parent_type_fk',)

    variant = Column(Text, nullable=False)

    description = Column(Text, doc="""
    Human-readable description.

    :type: :obj:`basestring`
    """)

    _role = Column(Text, name='role')

    # region one_to_one relationships

    @declared_attr
    def parent(cls):
        """
        Parent type (will be ``None`` for the root of a type hierarchy).

        :type: :class:`Type`
        """
        return relationship.one_to_one_self(cls, 'parent_type_fk')

    # endregion

    # region one_to_many relationships

    @declared_attr
    def children(cls):
        """
        Children.

        :type: [:class:`Type`]
        """
        return relationship.one_to_many(cls, other_fk='parent_type_fk', self=True)

    # endregion

    # region foreign keys

    @declared_attr
    def parent_type_fk(cls):
        """For Type one-to-many to Type"""
        return relationship.foreign_key('type', nullable=True)

    # endregion

    @property
    def role(self):
        def get_role(the_type):
            if the_type is None:
                return None
            elif the_type._role is None:
                return get_role(the_type.parent)
            return the_type._role

        return get_role(self)

    @role.setter
    def role(self, value):
        self._role = value

    def is_descendant(self, base_name, name):
        base = self.get_descendant(base_name)
        if base is not None:
            if base.get_descendant(name) is not None:
                return True
        return False

    def get_descendant(self, name):
        if self.name == name:
            return self
        for child in self.children:
            found = child.get_descendant(name)
            if found is not None:
                return found
        return None

    def iter_descendants(self):
        for child in self.children:
            yield child
            for descendant in child.iter_descendants():
                yield descendant

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('role', self.role)))

    @property
    def as_raw_all(self):
        types = []
        self._append_raw_children(types)
        return types

    def coerce_values(self, report_issues):
        pass

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        if self.name:
            console.puts(context.style.type(self.name))
        with context.style.indent:
            for child in self.children:
                child.dump()

    def _append_raw_children(self, types):
        for child in self.children:
            raw_child = formatting.as_raw(child)
            raw_child['parent'] = self.name
            types.append(raw_child)
            child._append_raw_children(types)

    @property
    def hierarchy(self):
        """
        Type hierarchy as a list beginning with this type and ending in the root.

        :type: [:class:`Type`]
        """
        return [self] + (self.parent.hierarchy if self.parent else [])


class MetadataBase(TemplateModelMixin):
    """
    Custom values associated with the service.

    This model is used by both service template and service instance elements.

    :ivar name: name
    :vartype name: basestring
    :ivar value: value
    :vartype value: basestring
    """

    __tablename__ = 'metadata'

    value = Column(Text)

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('value', self.value)))

    def coerce_values(self, report_issues):
        pass

    def instantiate(self, container):
        from . import models
        return models.Metadata(name=self.name,
                               value=self.value)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('{0}: {1}'.format(
            context.style.property(self.name),
            context.style.literal(self.value)))
