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

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

from sqlalchemy import (
    Column,
    Text,
    Integer,
    Enum,
    Boolean
)
from sqlalchemy import DateTime
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.orderinglist import ordering_list

from .mixins import InstanceModelMixin
from ..orchestrator import execution_plugin
from ..parser import validation
from ..parser.consumption import ConsumptionContext
from ..utils import collections, formatting, console
from . import (
    relationship,
    utils,
    types as modeling_types
)


class ServiceBase(InstanceModelMixin):
    """
    A service is usually an instance of a :class:`ServiceTemplate`.

    You will usually not create it programmatically, but instead instantiate it from a service
    template.

    :ivar name: Name (unique for this ARIA installation)
    :vartype name: basestring
    :ivar service_template: Template from which this service was instantiated (optional)
    :vartype service_template: :class:`ServiceTemplate`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar meta_data: Custom annotations
    :vartype meta_data: {basestring: :class:`Metadata`}
    :ivar node: Nodes
    :vartype node: {basestring: :class:`Node`}
    :ivar groups: Groups of nodes
    :vartype groups: {basestring: :class:`Group`}
    :ivar policies: Policies
    :vartype policies: {basestring: :class:`Policy`]}
    :ivar substitution: The entire service can appear as a node
    :vartype substitution: :class:`Substitution`
    :ivar inputs: Externally provided parameters
    :vartype inputs: {basestring: :class:`Parameter`}
    :ivar outputs: These parameters are filled in after service installation
    :vartype outputs: {basestring: :class:`Parameter`}
    :ivar workflows: Custom workflows that can be performed on the service
    :vartype workflows: {basestring: :class:`Operation`}
    :ivar plugins: Plugins used by the service
    :vartype plugins: {basestring: :class:`Plugin`}
    :ivar created_at: Creation timestamp
    :vartype created_at: :class:`datetime.datetime`
    :ivar updated_at: Update timestamp
    :vartype updated_at: :class:`datetime.datetime`
    :ivar modifications: Modifications of this service
    :vartype modifications: [:class:`ServiceModification`]
    :ivar updates: Updates of this service
    :vartype updates: [:class:`ServiceUpdate`]
    :ivar executions: Executions on this service
    :vartype executions: [:class:`Execution`]
    """

    __tablename__ = 'service'

    __private_fields__ = ['substitution_fk',
                          'service_template_fk']

    # region foreign keys

    @declared_attr
    def substitution_fk(cls):
        """Service one-to-one to Substitution"""
        return relationship.foreign_key('substitution', nullable=True)

    @declared_attr
    def service_template_fk(cls):
        """For Service many-to-one to ServiceTemplate"""
        return relationship.foreign_key('service_template', nullable=True)

    # endregion

    # region association proxies

    @declared_attr
    def service_template_name(cls):
        """Required for use by SQLAlchemy queries"""
        return association_proxy('service_template', 'name')

    # endregion

    # region one_to_one relationships

    @declared_attr
    def substitution(cls):
        return relationship.one_to_one(cls, 'substitution', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region one_to_many relationships

    @declared_attr
    def updates(cls):
        return relationship.one_to_many(cls, 'service_update')

    @declared_attr
    def modifications(cls):
        return relationship.one_to_many(cls, 'service_modification')

    @declared_attr
    def executions(cls):
        return relationship.one_to_many(cls, 'execution')

    @declared_attr
    def nodes(cls):
        return relationship.one_to_many(cls, 'node', dict_key='name')

    @declared_attr
    def groups(cls):
        return relationship.one_to_many(cls, 'group', dict_key='name')

    @declared_attr
    def policies(cls):
        return relationship.one_to_many(cls, 'policy', dict_key='name')

    @declared_attr
    def workflows(cls):
        return relationship.one_to_many(cls, 'operation', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        return relationship.many_to_one(cls, 'service_template')

    # endregion

    # region many_to_many relationships

    @declared_attr
    def meta_data(cls):
        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
        return relationship.many_to_many(cls, 'metadata', dict_key='name')

    @declared_attr
    def inputs(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')

    @declared_attr
    def outputs(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='outputs', dict_key='name')

    @declared_attr
    def plugins(cls):
        return relationship.many_to_many(cls, 'plugin', dict_key='name')

    # endregion

    description = Column(Text)
    created_at = Column(DateTime, nullable=False, index=True)
    updated_at = Column(DateTime)

    def satisfy_requirements(self):
        satisfied = True
        for node in self.nodes.itervalues():
            if not node.satisfy_requirements():
                satisfied = False
        return satisfied

    def validate_capabilities(self):
        satisfied = True
        for node in self.nodes.itervalues():
            if not node.validate_capabilities():
                satisfied = False
        return satisfied

    def find_hosts(self):
        for node in self.nodes.itervalues():
            node.find_host()

    def configure_operations(self):
        for node in self.nodes.itervalues():
            node.configure_operations()
        for group in self.groups.itervalues():
            group.configure_operations()
        for operation in self.workflows.itervalues():
            operation.configure()

    def is_node_a_target(self, target_node):
        for node in self.nodes.itervalues():
            if self._is_node_a_target(node, target_node):
                return True
        return False

    def _is_node_a_target(self, source_node, target_node):
        if source_node.outbound_relationships:
            for relationship_model in source_node.outbound_relationships:
                if relationship_model.target_node.name == target_node.name:
                    return True
                else:
                    node = relationship_model.target_node
                    if node is not None:
                        if self._is_node_a_target(node, target_node):
                            return True
        return False

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('description', self.description),
            ('metadata', formatting.as_raw_dict(self.meta_data)),
            ('nodes', formatting.as_raw_list(self.nodes)),
            ('groups', formatting.as_raw_list(self.groups)),
            ('policies', formatting.as_raw_list(self.policies)),
            ('substitution', formatting.as_raw(self.substitution)),
            ('inputs', formatting.as_raw_dict(self.inputs)),
            ('outputs', formatting.as_raw_dict(self.outputs)),
            ('workflows', formatting.as_raw_list(self.workflows))))

    def validate(self):
        utils.validate_dict_values(self.meta_data)
        utils.validate_dict_values(self.nodes)
        utils.validate_dict_values(self.groups)
        utils.validate_dict_values(self.policies)
        if self.substitution is not None:
            self.substitution.validate()
        utils.validate_dict_values(self.inputs)
        utils.validate_dict_values(self.outputs)
        utils.validate_dict_values(self.workflows)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.meta_data, report_issues)
        utils.coerce_dict_values(self.nodes, report_issues)
        utils.coerce_dict_values(self.groups, report_issues)
        utils.coerce_dict_values(self.policies, report_issues)
        if self.substitution is not None:
            self.substitution.coerce_values(report_issues)
        utils.coerce_dict_values(self.inputs, report_issues)
        utils.coerce_dict_values(self.outputs, report_issues)
        utils.coerce_dict_values(self.workflows, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        if self.description is not None:
            console.puts(context.style.meta(self.description))
        utils.dump_dict_values(self.meta_data, 'Metadata')
        for node in self.nodes.itervalues():
            node.dump()
        for group in self.groups.itervalues():
            group.dump()
        for policy in self.policies.itervalues():
            policy.dump()
        if self.substitution is not None:
            self.substitution.dump()
        utils.dump_dict_values(self.inputs, 'Inputs')
        utils.dump_dict_values(self.outputs, 'Outputs')
        utils.dump_dict_values(self.workflows, 'Workflows')

    def dump_graph(self):
        for node in self.nodes.itervalues():
            if not self.is_node_a_target(node):
                self._dump_graph_node(node)

    def _dump_graph_node(self, node, capability=None):
        context = ConsumptionContext.get_thread_local()
        console.puts(context.style.node(node.name))
        if capability is not None:
            console.puts('{0} ({1})'.format(context.style.property(capability.name),
                                            context.style.type(capability.type.name)))
        if node.outbound_relationships:
            with context.style.indent:
                for relationship_model in node.outbound_relationships:
                    relationship_name = context.style.property(relationship_model.name)
                    if relationship_model.type is not None:
                        console.puts('-> {0} ({1})'.format(relationship_name,
                                                           context.style.type(
                                                               relationship_model.type.name)))
                    else:
                        console.puts('-> {0}'.format(relationship_name))
                    with console.indent(3):
                        self._dump_graph_node(relationship_model.target_node,
                                              relationship_model.target_capability)


class NodeBase(InstanceModelMixin):
    """
    Usually an instance of a :class:`NodeTemplate`.

    Nodes may have zero or more :class:`Relationship` instances to other nodes.

    :ivar name: Name (unique for this service)
    :vartype name: basestring
    :ivar node_template: Template from which this node was instantiated (optional)
    :vartype node_template: :class:`NodeTemplate`
    :ivar type: Node type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interfaces: Bundles of operations
    :vartype interfaces: {basestring: :class:`Interface`}
    :ivar artifacts: Associated files
    :vartype artifacts: {basestring: :class:`Artifact`}
    :ivar capabilities: Exposed capabilities
    :vartype capabilities: {basestring: :class:`Capability`}
    :ivar outbound_relationships: Relationships to other nodes
    :vartype outbound_relationships: [:class:`Relationship`]
    :ivar inbound_relationships: Relationships from other nodes
    :vartype inbound_relationships: [:class:`Relationship`]
    :ivar host: Host node (can be self)
    :vartype host: :class:`Node`
    :ivar runtime_properties: TODO: should be replaced with attributes
    :vartype runtime_properties: {}
    :ivar state: The state of the node, according to to the TOSCA-defined node states
    :vartype state: string
    :ivar version: Used by `aria.storage.instrumentation`
    :vartype version: int
    :ivar service: Containing service
    :vartype service: :class:`Service`
    :ivar groups: We are a member of these groups
    :vartype groups: [:class:`Group`]
    :ivar policies: Policies enacted on this node
    :vartype policies: [:class:`Policy`]
    :ivar substitution_mapping: Our contribution to service substitution
    :vartype substitution_mapping: :class:`SubstitutionMapping`
    :ivar tasks: Tasks for this node
    :vartype tasks: [:class:`Task`]
    :ivar hosted_tasks: Tasks on this node
    :vartype hosted_tasks: [:class:`Task`]
    """

    __tablename__ = 'node'

    __private_fields__ = ['type_fk',
                          'host_fk',
                          'service_fk',
                          'node_template_fk']

    INITIAL = 'initial'
    CREATING = 'creating'
    CREATED = 'created'
    CONFIGURING = 'configuring'
    CONFIGURED = 'configured'
    STARTING = 'starting'
    STARTED = 'started'
    STOPPING = 'stopping'
    DELETING = 'deleting'
    # 'deleted' isn't actually part of the tosca spec, since according the description of the
    # 'deleting' state: "Node is transitioning from its current state to one where it is deleted and
    #  its state is no longer tracked by the instance model."
    # However, we prefer to be able to retrieve information about deleted nodes, so we chose to add
    # this 'deleted' state to enable us to do so.
    DELETED = 'deleted'
    ERROR = 'error'

    STATES = [INITIAL, CREATING, CREATED, CONFIGURING, CONFIGURED, STARTING, STARTED, STOPPING,
              DELETING, DELETED, ERROR]

    _op_to_state = {'create': {'transitional': CREATING, 'finished': CREATED},
                    'configure': {'transitional': CONFIGURING, 'finished': CONFIGURED},
                    'start': {'transitional': STARTING, 'finished': STARTED},
                    'stop': {'transitional': STOPPING, 'finished': CONFIGURED},
                    'delete': {'transitional': DELETING, 'finished': DELETED}}

    @classmethod
    def determine_state(cls, op_name, is_transitional):
        """ :returns the state the node should be in as a result of running the
            operation on this node.

            e.g. if we are running tosca.interfaces.node.lifecycle.Standard.create, then
            the resulting state should either 'creating' (if the task just started) or 'created'
            (if the task ended).

            If the operation is not a standard tosca lifecycle operation, then we return None"""

        state_type = 'transitional' if is_transitional else 'finished'
        try:
            return cls._op_to_state[op_name][state_type]
        except KeyError:
            return None

    def is_available(self):
        return self.state not in (self.INITIAL, self.DELETED, self.ERROR)

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Node many-to-one to Type"""
        return relationship.foreign_key('type')

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

    @declared_attr
    def service_fk(cls):
        """For Service one-to-many to Node"""
        return relationship.foreign_key('service')

    @declared_attr
    def node_template_fk(cls):
        """For Node many-to-one to NodeTemplate"""
        return relationship.foreign_key('node_template')

    # endregion

    # region association proxies

    @declared_attr
    def service_name(cls):
        """Required for use by SQLAlchemy queries"""
        return association_proxy('service', 'name')

    @declared_attr
    def node_template_name(cls):
        """Required for use by SQLAlchemy queries"""
        return association_proxy('node_template', 'name')

    # endregion

    # region one_to_one relationships

    @declared_attr
    def host(cls): # pylint: disable=method-hidden
        return relationship.one_to_one_self(cls, 'host_fk')

    # endregion

    # region one_to_many relationships

    @declared_attr
    def tasks(cls):
        return relationship.one_to_many(cls, 'task')

    @declared_attr
    def interfaces(cls):
        return relationship.one_to_many(cls, 'interface', dict_key='name')

    @declared_attr
    def artifacts(cls):
        return relationship.one_to_many(cls, 'artifact', dict_key='name')

    @declared_attr
    def capabilities(cls):
        return relationship.one_to_many(cls, 'capability', dict_key='name')

    @declared_attr
    def outbound_relationships(cls):
        return relationship.one_to_many(
            cls, 'relationship', child_fk='source_node_fk', back_populates='source_node',
            rel_kwargs=dict(
                order_by='Relationship.source_position',
                collection_class=ordering_list('source_position', count_from=0)
            )
        )

    @declared_attr
    def inbound_relationships(cls):
        return relationship.one_to_many(
            cls, 'relationship', child_fk='target_node_fk', back_populates='target_node',
            rel_kwargs=dict(
                order_by='Relationship.target_position',
                collection_class=ordering_list('target_position', count_from=0)
            )
        )

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service(cls):
        return relationship.many_to_one(cls, 'service')

    @declared_attr
    def node_template(cls):
        return relationship.many_to_one(cls, 'node_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships
    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')

    @declared_attr
    def attributes(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='attributes', dict_key='name')

    # endregion

    description = Column(Text)
    runtime_properties = Column(modeling_types.Dict)
    state = Column(Enum(*STATES, name='node_state'), nullable=False, default=INITIAL)
    version = Column(Integer, default=1)

    __mapper_args__ = {'version_id_col': version} # Enable SQLAlchemy automatic version counting

    @property
    def host_address(self):
        if self.host and self.host.runtime_properties:
            return self.host.runtime_properties.get('ip')
        return None

    def satisfy_requirements(self):
        node_template = self.node_template
        satisfied = True
        for requirement_template in node_template.requirement_templates:
            # Find target template
            target_node_template, target_node_capability = \
                requirement_template.find_target(node_template)
            if target_node_template is not None:
                satisfied = self._satisfy_capability(target_node_capability,
                                                     target_node_template,
                                                     requirement_template)
            else:
                context = ConsumptionContext.get_thread_local()
                context.validation.report('requirement "{0}" of node "{1}" has no target node '
                                          'template'.format(requirement_template.name, self.name),
                                          level=validation.Issue.BETWEEN_INSTANCES)
                satisfied = False
        return satisfied

    def _satisfy_capability(self, target_node_capability, target_node_template,
                            requirement_template):
        from . import models
        context = ConsumptionContext.get_thread_local()
        # Find target nodes
        target_nodes = target_node_template.nodes
        if target_nodes:
            target_node = None
            target_capability = None

            if target_node_capability is not None:
                # Relate to the first target node that has capacity
                for node in target_nodes:
                    a_target_capability = node.capabilities.get(target_node_capability.name)
                    if a_target_capability.relate():
                        target_node = node
                        target_capability = a_target_capability
                        break
            else:
                # Use first target node
                target_node = target_nodes[0]

            if target_node is not None:
                if requirement_template.relationship_template is not None:
                    relationship_model = \
                        requirement_template.relationship_template.instantiate(self)
                else:
                    relationship_model = models.Relationship()
                relationship_model.name = requirement_template.name
                relationship_model.requirement_template = requirement_template
                relationship_model.target_node = target_node
                relationship_model.target_capability = target_capability
                self.outbound_relationships.append(relationship_model)
                return True
            else:
                context.validation.report('requirement "{0}" of node "{1}" targets node '
                                          'template "{2}" but its instantiated nodes do not '
                                          'have enough capacity'.format(
                                              requirement_template.name,
                                              self.name,
                                              target_node_template.name),
                                          level=validation.Issue.BETWEEN_INSTANCES)
                return False
        else:
            context.validation.report('requirement "{0}" of node "{1}" targets node template '
                                      '"{2}" but it has no instantiated nodes'.format(
                                          requirement_template.name,
                                          self.name,
                                          target_node_template.name),
                                      level=validation.Issue.BETWEEN_INSTANCES)
            return False

    def validate_capabilities(self):
        context = ConsumptionContext.get_thread_local()
        satisfied = False
        for capability in self.capabilities.itervalues():
            if not capability.has_enough_relationships:
                context.validation.report('capability "{0}" of node "{1}" requires at least {2:d} '
                                          'relationships but has {3:d}'.format(
                                              capability.name,
                                              self.name,
                                              capability.min_occurrences,
                                              capability.occurrences),
                                          level=validation.Issue.BETWEEN_INSTANCES)
                satisfied = False
        return satisfied

    def find_host(self):
        def _find_host(node):
            if node.type.role == 'host':
                return node
            for the_relationship in node.outbound_relationships:
                if (the_relationship.target_capability is not None) and \
                    the_relationship.target_capability.type.role == 'host':
                    host = _find_host(the_relationship.target_node)
                    if host is not None:
                        return host
            for the_relationship in node.inbound_relationships:
                if (the_relationship.target_capability is not None) and \
                    the_relationship.target_capability.type.role == 'feature':
                    host = _find_host(the_relationship.source_node)
                    if host is not None:
                        return host
            return None

        self.host = _find_host(self)

    def configure_operations(self):
        for interface in self.interfaces.itervalues():
            interface.configure_operations()
        for the_relationship in self.outbound_relationships:
            the_relationship.configure_operations()

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('type_name', self.type.name),
            ('properties', formatting.as_raw_dict(self.properties)),
            ('attributes', formatting.as_raw_dict(self.properties)),
            ('interfaces', formatting.as_raw_list(self.interfaces)),
            ('artifacts', formatting.as_raw_list(self.artifacts)),
            ('capabilities', formatting.as_raw_list(self.capabilities)),
            ('relationships', formatting.as_raw_list(self.outbound_relationships))))

    def validate(self):
        context = ConsumptionContext.get_thread_local()
        if len(self.name) > context.modeling.id_max_length:
            context.validation.report('"{0}" has an ID longer than the limit of {1:d} characters: '
                                      '{2:d}'.format(
                                          self.name,
                                          context.modeling.id_max_length,
                                          len(self.name)),
                                      level=validation.Issue.BETWEEN_INSTANCES)

        # TODO: validate that node template is of type?

        utils.validate_dict_values(self.properties)
        utils.validate_dict_values(self.attributes)
        utils.validate_dict_values(self.interfaces)
        utils.validate_dict_values(self.artifacts)
        utils.validate_dict_values(self.capabilities)
        utils.validate_list_values(self.outbound_relationships)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)
        utils.coerce_dict_values(self.attributes, report_issues)
        utils.coerce_dict_values(self.interfaces, report_issues)
        utils.coerce_dict_values(self.artifacts, report_issues)
        utils.coerce_dict_values(self.capabilities, report_issues)
        utils.coerce_list_values(self.outbound_relationships, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Node: {0}'.format(context.style.node(self.name)))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            console.puts('Template: {0}'.format(context.style.node(self.node_template.name)))
            utils.dump_dict_values(self.properties, 'Properties')
            utils.dump_dict_values(self.attributes, 'Attributes')
            utils.dump_interfaces(self.interfaces)
            utils.dump_dict_values(self.artifacts, 'Artifacts')
            utils.dump_dict_values(self.capabilities, 'Capabilities')
            utils.dump_list_values(self.outbound_relationships, 'Relationships')


class GroupBase(InstanceModelMixin):
    """
    Usually an instance of a :class:`GroupTemplate`.

    :ivar name: Name (unique for this service)
    :vartype name: basestring
    :ivar group_template: Template from which this group was instantiated (optional)
    :vartype group_template: :class:`GroupTemplate`
    :ivar type: Group type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar nodes: Members of this group
    :vartype nodes: [:class:`Node`]
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interfaces: Bundles of operations
    :vartype interfaces: {basestring: :class:`Interface`}
    :ivar service: Containing service
    :vartype service: :class:`Service`
    :ivar policies: Policies enacted on this group
    :vartype policies: [:class:`Policy`]
    """

    __tablename__ = 'group'

    __private_fields__ = ['type_fk', 'service_fk', 'group_template_fk']

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Group many-to-one to Type"""
        return relationship.foreign_key('type')

    @declared_attr
    def service_fk(cls):
        """For Service one-to-many to Group"""
        return relationship.foreign_key('service')

    @declared_attr
    def group_template_fk(cls):
        """For Group many-to-one to GroupTemplate"""
        return relationship.foreign_key('group_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def interfaces(cls):
        return relationship.one_to_many(cls, 'interface', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service(cls):
        return relationship.many_to_one(cls, 'service')

    @declared_attr
    def group_template(cls):
        return relationship.many_to_one(cls, 'group_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    @declared_attr
    def nodes(cls):
        return relationship.many_to_many(cls, 'node')

    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')

    # endregion

    description = Column(Text)

    def configure_operations(self):
        for interface in self.interfaces.itervalues():
            interface.configure_operations()

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('properties', formatting.as_raw_dict(self.properties)),
            ('interfaces', formatting.as_raw_list(self.interfaces))))

    def validate(self):
        utils.validate_dict_values(self.properties)
        utils.validate_dict_values(self.interfaces)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)
        utils.coerce_dict_values(self.interfaces, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Group: {0}'.format(context.style.node(self.name)))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            utils.dump_dict_values(self.properties, 'Properties')
            utils.dump_interfaces(self.interfaces)
            if self.nodes:
                console.puts('Member nodes:')
                with context.style.indent:
                    for node in self.nodes:
                        console.puts(context.style.node(node.name))


class PolicyBase(InstanceModelMixin):
    """
    Usually an instance of a :class:`PolicyTemplate`.

    :ivar name: Name (unique for this service)
    :vartype name: basestring
    :ivar policy_template: Template from which this policy was instantiated (optional)
    :vartype policy_template: :class:`PolicyTemplate`
    :ivar type: Policy type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar nodes: Policy will be enacted on all these nodes
    :vartype nodes: [:class:`Node`]
    :ivar groups: Policy will be enacted on all nodes in these groups
    :vartype groups: [:class:`Group`]
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar service: Containing service
    :vartype service: :class:`Service`
    """

    __tablename__ = 'policy'

    __private_fields__ = ['type_fk', 'service_fk', 'policy_template_fk']

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Policy many-to-one to Type"""
        return relationship.foreign_key('type')

    @declared_attr
    def service_fk(cls):
        """For Service one-to-many to Policy"""
        return relationship.foreign_key('service')

    @declared_attr
    def policy_template_fk(cls):
        """For Policy many-to-one to PolicyTemplate"""
        return relationship.foreign_key('policy_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service(cls):
        return relationship.many_to_one(cls, 'service')

    @declared_attr
    def policy_template(cls):
        return relationship.many_to_one(cls, 'policy_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')

    @declared_attr
    def nodes(cls):
        return relationship.many_to_many(cls, 'node')

    @declared_attr
    def groups(cls):
        return relationship.many_to_many(cls, 'group')

    # endregion

    description = Column(Text)

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('type_name', self.type.name),
            ('properties', formatting.as_raw_dict(self.properties))))

    def validate(self):
        utils.validate_dict_values(self.properties)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Policy: {0}'.format(context.style.node(self.name)))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            utils.dump_dict_values(self.properties, 'Properties')
            if self.nodes:
                console.puts('Target nodes:')
                with context.style.indent:
                    for node in self.nodes:
                        console.puts(context.style.node(node.name))
            if self.groups:
                console.puts('Target groups:')
                with context.style.indent:
                    for group in self.groups:
                        console.puts(context.style.node(group.name))


class SubstitutionBase(InstanceModelMixin):
    """
    Used to substitute a single node for the entire deployment.

    Usually an instance of a :class:`SubstitutionTemplate`.

    :ivar substitution_template: Template from which this substitution was instantiated (optional)
    :vartype substitution_template: :class:`SubstitutionTemplate`
    :ivar node_type: Exposed node type
    :vartype node_type: :class:`Type`
    :ivar mappings: Requirement and capability mappings
    :vartype mappings: {basestring: :class:`SubstitutionTemplate`}
    :ivar service: Containing service
    :vartype service: :class:`Service`
    """

    __tablename__ = 'substitution'

    __private_fields__ = ['node_type_fk',
                          'substitution_template_fk']

    # region foreign_keys

    @declared_attr
    def node_type_fk(cls):
        """For Substitution many-to-one to Type"""
        return relationship.foreign_key('type')

    @declared_attr
    def substitution_template_fk(cls):
        """For Substitution many-to-one to SubstitutionTemplate"""
        return relationship.foreign_key('substitution_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def mappings(cls):
        return relationship.one_to_many(cls, 'substitution_mapping', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service(cls):
        return relationship.one_to_one(cls, 'service', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def substitution_template(cls):
        return relationship.many_to_one(cls, 'substitution_template')

    @declared_attr
    def node_type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    # endregion

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('node_type_name', self.node_type.name),
            ('mappings', formatting.as_raw_dict(self.mappings))))

    def validate(self):
        utils.validate_dict_values(self.mappings)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.mappings, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Substitution:')
        with context.style.indent:
            console.puts('Node type: {0}'.format(context.style.type(self.node_type.name)))
            utils.dump_dict_values(self.mappings, 'Mappings')


class SubstitutionMappingBase(InstanceModelMixin):
    """
    Used by :class:`Substitution` to map a capability or a requirement to a node.

    Only one of `capability_template` and `requirement_template` can be set.

    Usually an instance of a :class:`SubstitutionTemplate`.

    :ivar name: Exposed capability or requirement name
    :vartype name: basestring
    :ivar node: Node
    :vartype node: :class:`Node`
    :ivar capability: Capability in the node
    :vartype capability: :class:`Capability`
    :ivar requirement_template: Requirement template in the node template
    :vartype requirement_template: :class:`RequirementTemplate`
    :ivar substitution: Containing substitution
    :vartype substitution: :class:`Substitution`
    """

    __tablename__ = 'substitution_mapping'

    __private_fields__ = ['substitution_fk',
                          'node_fk',
                          'capability_fk',
                          'requirement_template_fk']

    # region foreign keys

    @declared_attr
    def substitution_fk(cls):
        """For Substitution one-to-many to SubstitutionMapping"""
        return relationship.foreign_key('substitution')

    @declared_attr
    def node_fk(cls):
        """For Substitution one-to-one to NodeTemplate"""
        return relationship.foreign_key('node')

    @declared_attr
    def capability_fk(cls):
        """For Substitution one-to-one to Capability"""
        return relationship.foreign_key('capability', nullable=True)

    @declared_attr
    def requirement_template_fk(cls):
        """For Substitution one-to-one to RequirementTemplate"""
        return relationship.foreign_key('requirement_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def substitution(cls):
        return relationship.many_to_one(cls, 'substitution', back_populates='mappings')

    @declared_attr
    def node(cls):
        return relationship.one_to_one(cls, 'node', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def capability(cls):
        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def requirement_template(cls):
        return relationship.one_to_one(
            cls, 'requirement_template', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region one_to_many relationships

    # endregion

    # region many_to_one relationships

    # endregion

    # region many_to_many relationships

    # endregion

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

    def coerce_values(self, report_issues):
        pass

    def validate(self):
        context = ConsumptionContext.get_thread_local()
        if (self.capability is None) and (self.requirement_template is None):
            context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
                                      ' in node: {1}'.format(
                                          self.name,
                                          formatting.safe_repr(self.node.name)),
                                      level=validation.Issue.BETWEEN_TYPES)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('{0} -> {1}.{2}'.format(
            context.style.node(self.name),
            context.style.node(self.node.name),
            context.style.node(self.capability.name
                               if self.capability
                               else self.requirement_template.name)))


class RelationshipBase(InstanceModelMixin):
    """
    Connects :class:`Node` to a capability in another node.

    Might be an instance of a :class:`RelationshipTemplate`.

    :ivar name: Name (usually the name of the requirement at the source node template)
    :vartype name: basestring
    :ivar relationship_template: Template from which this relationship was instantiated (optional)
    :vartype relationship_template: :class:`RelationshipTemplate`
    :ivar requirement_template: Template from which this relationship was instantiated (optional)
    :vartype requirement_template: :class:`RequirementTemplate`
    :ivar type: Relationship type
    :vartype type: :class:`Type`
    :ivar target_capability: Capability at the target node (optional)
    :vartype target_capability: :class:`Capability`
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interfaces: Bundles of operations
    :vartype interfaces: {basestring: :class:`Interfaces`}
    :ivar source_position: The position of the relationship in the outbound relationships.
    :vartype source_position: int
    :ivar target_position: The position of the relationship in the inbound relationships.
    :vartype target_position: int
    :ivar source_node: Source node
    :vartype source_node: :class:`Node`
    :ivar target_node: Target node
    :vartype target_node: :class:`Node`
    :ivar tasks: Tasks for this relationship
    :vartype tasks: [:class:`Task`]
    """

    __tablename__ = 'relationship'

    __private_fields__ = ['type_fk',
                          'source_node_fk',
                          'target_node_fk',
                          'target_capability_fk',
                          'requirement_template_fk',
                          'relationship_template_fk',
                          'target_position',
                          'source_position']

    # region foreign keys

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

    @declared_attr
    def source_node_fk(cls):
        """For Node one-to-many to Relationship"""
        return relationship.foreign_key('node')

    @declared_attr
    def target_node_fk(cls):
        """For Node one-to-many to Relationship"""
        return relationship.foreign_key('node')

    @declared_attr
    def target_capability_fk(cls):
        """For Relationship one-to-one to Capability"""
        return relationship.foreign_key('capability', nullable=True)

    @declared_attr
    def requirement_template_fk(cls):
        """For Relationship many-to-one to RequirementTemplate"""
        return relationship.foreign_key('requirement_template', nullable=True)

    @declared_attr
    def relationship_template_fk(cls):
        """For Relationship many-to-one to RelationshipTemplate"""
        return relationship.foreign_key('relationship_template', nullable=True)

    # endregion

    # region association proxies

    @declared_attr
    def source_node_name(cls):
        """Required for use by SQLAlchemy queries"""
        return association_proxy('source_node', 'name')

    @declared_attr
    def target_node_name(cls):
        """Required for use by SQLAlchemy queries"""
        return association_proxy('target_node', 'name')

    # endregion

    # region one_to_one relationships

    @declared_attr
    def target_capability(cls):
        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region one_to_many relationships

    @declared_attr
    def tasks(cls):
        return relationship.one_to_many(cls, 'task')

    @declared_attr
    def interfaces(cls):
        return relationship.one_to_many(cls, 'interface', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def source_node(cls):
        return relationship.many_to_one(
            cls, 'node', fk='source_node_fk', back_populates='outbound_relationships')

    @declared_attr
    def target_node(cls):
        return relationship.many_to_one(
            cls, 'node', fk='target_node_fk', back_populates='inbound_relationships')

    @declared_attr
    def relationship_template(cls):
        return relationship.many_to_one(cls, 'relationship_template')

    @declared_attr
    def requirement_template(cls):
        return relationship.many_to_one(cls, 'requirement_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')

    # endregion

    source_position = Column(Integer)
    target_position = Column(Integer)

    def configure_operations(self):
        for interface in self.interfaces.itervalues():
            interface.configure_operations()

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('target_node_id', self.target_node.name),
            ('type_name', self.type.name
             if self.type is not None else None),
            ('template_name', self.relationship_template.name
             if self.relationship_template is not None else None),
            ('properties', formatting.as_raw_dict(self.properties)),
            ('interfaces', formatting.as_raw_list(self.interfaces))))

    def validate(self):
        utils.validate_dict_values(self.properties)
        utils.validate_dict_values(self.interfaces)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)
        utils.coerce_dict_values(self.interfaces, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        if self.name:
            console.puts('{0} ->'.format(context.style.node(self.name)))
        else:
            console.puts('->')
        with context.style.indent:
            console.puts('Node: {0}'.format(context.style.node(self.target_node.name)))
            if self.target_capability:
                console.puts('Capability: {0}'.format(context.style.node(
                    self.target_capability.name)))
            if self.type is not None:
                console.puts('Relationship type: {0}'.format(context.style.type(self.type.name)))
            if (self.relationship_template is not None) and self.relationship_template.name:
                console.puts('Relationship template: {0}'.format(
                    context.style.node(self.relationship_template.name)))
            utils.dump_dict_values(self.properties, 'Properties')
            utils.dump_interfaces(self.interfaces, 'Interfaces')


class CapabilityBase(InstanceModelMixin):
    """
    A capability of a :class:`Node`.

    Usually an instance of a :class:`CapabilityTemplate`.

    :ivar name: Name (unique for the node)
    :vartype name: basestring
    :ivar capability_template: Template from which this capability was instantiated (optional)
    :vartype capability_template: :class:`capabilityTemplate`
    :ivar type: Capability type
    :vartype type: :class:`Type`
    :ivar min_occurrences: Minimum number of requirement matches required
    :vartype min_occurrences: int
    :ivar max_occurrences: Maximum number of requirement matches allowed
    :vartype min_occurrences: int
    :ivar occurrences: Actual number of requirement matches
    :vartype occurrences: int
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar node: Containing node
    :vartype node: :class:`Node`
    :ivar relationship: Available when we are the target of a relationship
    :vartype relationship: :class:`Relationship`
    :ivar substitution_mapping: Our contribution to service substitution
    :vartype substitution_mapping: :class:`SubstitutionMapping`
    """

    __tablename__ = 'capability'

    __private_fields__ = ['capability_fk',
                          'node_fk',
                          'capability_template_fk']

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Capability many-to-one to Type"""
        return relationship.foreign_key('type')

    @declared_attr
    def node_fk(cls):
        """For Node one-to-many to Capability"""
        return relationship.foreign_key('node')

    @declared_attr
    def capability_template_fk(cls):
        """For Capability many-to-one to CapabilityTemplate"""
        return relationship.foreign_key('capability_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node(cls):
        return relationship.many_to_one(cls, 'node')

    @declared_attr
    def capability_template(cls):
        return relationship.many_to_one(cls, 'capability_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')

    # endregion

    min_occurrences = Column(Integer, default=None)
    max_occurrences = Column(Integer, default=None)
    occurrences = Column(Integer, default=0)

    @property
    def has_enough_relationships(self):
        if self.min_occurrences is not None:
            return self.occurrences >= self.min_occurrences
        return True

    def relate(self):
        if self.max_occurrences is not None:
            if self.occurrences == self.max_occurrences:
                return False
        self.occurrences += 1
        return True

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('type_name', self.type.name),
            ('properties', formatting.as_raw_dict(self.properties))))

    def validate(self):
        utils.validate_dict_values(self.properties)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts(context.style.node(self.name))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            console.puts('Occurrences: {0:d} ({1:d}{2})'.format(
                self.occurrences,
                self.min_occurrences or 0,
                ' to {0:d}'.format(self.max_occurrences)
                if self.max_occurrences is not None
                else ' or more'))
            utils.dump_dict_values(self.properties, 'Properties')


class InterfaceBase(InstanceModelMixin):
    """
    A typed set of :class:`Operation`.

    Usually an instance of :class:`InterfaceTemplate`.

    :ivar name: Name (unique for the node, group, or relationship)
    :vartype name: basestring
    :ivar interface_template: Template from which this interface was instantiated (optional)
    :vartype interface_template: :class:`InterfaceTemplate`
    :ivar type: Interface type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar inputs: Parameters that can be used by all operations in the interface
    :vartype inputs: {basestring: :class:`Parameter`}
    :ivar operations: Operations
    :vartype operations: {basestring: :class:`Operation`}
    :ivar node: Containing node
    :vartype node: :class:`Node`
    :ivar group: Containing group
    :vartype group: :class:`Group`
    :ivar relationship: Containing relationship
    :vartype relationship: :class:`Relationship`
    """

    __tablename__ = 'interface'

    __private_fields__ = ['type_fk',
                          'node_fk',
                          'group_fk',
                          'relationship_fk',
                          'interface_template_fk']

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Interface many-to-one to Type"""
        return relationship.foreign_key('type')

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

    @declared_attr
    def group_fk(cls):
        """For Group one-to-many to Interface"""
        return relationship.foreign_key('group', nullable=True)

    @declared_attr
    def relationship_fk(cls):
        """For Relationship one-to-many to Interface"""
        return relationship.foreign_key('relationship', nullable=True)

    @declared_attr
    def interface_template_fk(cls):
        """For Interface many-to-one to InterfaceTemplate"""
        return relationship.foreign_key('interface_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def operations(cls):
        return relationship.one_to_many(cls, 'operation', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node(cls):
        return relationship.many_to_one(cls, 'node')

    @declared_attr
    def relationship(cls):
        return relationship.many_to_one(cls, 'relationship')

    @declared_attr
    def group(cls):
        return relationship.many_to_one(cls, 'group')

    @declared_attr
    def interface_template(cls):
        return relationship.many_to_one(cls, 'interface_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region many_to_many relationships

    @declared_attr
    def inputs(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')

    # endregion

    description = Column(Text)

    def configure_operations(self):
        for operation in self.operations.itervalues():
            operation.configure()

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('type_name', self.type.name),
            ('inputs', formatting.as_raw_dict(self.inputs)),
            ('operations', formatting.as_raw_list(self.operations))))

    def validate(self):
        utils.validate_dict_values(self.inputs)
        utils.validate_dict_values(self.operations)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.inputs, report_issues)
        utils.coerce_dict_values(self.operations, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts(context.style.node(self.name))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            console.puts('Interface type: {0}'.format(context.style.type(self.type.name)))
            utils.dump_dict_values(self.inputs, 'Inputs')
            utils.dump_dict_values(self.operations, 'Operations')


class OperationBase(InstanceModelMixin):
    """
    An operation in a :class:`Interface`.

    Might be an instance of :class:`OperationTemplate`.

    :ivar name: Name (unique for the interface or service)
    :vartype name: basestring
    :ivar operation_template: Template from which this operation was instantiated (optional)
    :vartype operation_template: :class:`OperationTemplate`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar plugin: Associated plugin
    :vartype plugin: :class:`Plugin`
    :ivar relationship_edge: When true specified that the operation is on the relationship's
                             target edge instead of its source (only used by relationship
                             operations)
    :vartype relationship_edge: bool
    :ivar implementation: Implementation (interpreted by the plugin)
    :vartype implementation: basestring
    :ivar configuration: Configuration (interpreted by the plugin)
    :vartype configuration: {basestring, object}
    :ivar dependencies: Dependency strings (interpreted by the plugin)
    :vartype dependencies: [basestring]
    :ivar inputs: Parameters that can be used by this operation
    :vartype inputs: {basestring: :class:`Parameter`}
    :ivar executor: Name of executor to run the operation with
    :vartype executor: basestring
    :ivar max_attempts: Maximum number of attempts allowed in case of failure
    :vartype max_attempts: int
    :ivar retry_interval: Interval between retries (in seconds)
    :vartype retry_interval: int
    :ivar interface: Containing interface
    :vartype interface: :class:`Interface`
    :ivar service: Containing service
    :vartype service: :class:`Service`
    """

    __tablename__ = 'operation'

    __private_fields__ = ['service_fk',
                          'interface_fk',
                          'plugin_fk',
                          'operation_template_fk']

    # region foreign_keys

    @declared_attr
    def service_fk(cls):
        """For Service one-to-many to Operation"""
        return relationship.foreign_key('service', nullable=True)

    @declared_attr
    def interface_fk(cls):
        """For Interface one-to-many to Operation"""
        return relationship.foreign_key('interface', nullable=True)

    @declared_attr
    def plugin_fk(cls):
        """For Operation one-to-one to Plugin"""
        return relationship.foreign_key('plugin', nullable=True)

    @declared_attr
    def operation_template_fk(cls):
        """For Operation many-to-one to OperationTemplate"""
        return relationship.foreign_key('operation_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def plugin(cls):
        return relationship.one_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region one_to_many relationships

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service(cls):
        return relationship.many_to_one(cls, 'service', back_populates='workflows')

    @declared_attr
    def interface(cls):
        return relationship.many_to_one(cls, 'interface')

    @declared_attr
    def operation_template(cls):
        return relationship.many_to_one(cls, 'operation_template')

    # endregion

    # region many_to_many relationships

    @declared_attr
    def inputs(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')

    # endregion

    description = Column(Text)
    relationship_edge = Column(Boolean)
    implementation = Column(Text)
    configuration = Column(modeling_types.StrictDict(key_cls=basestring))
    dependencies = Column(modeling_types.StrictList(item_cls=basestring))
    executor = Column(Text)
    max_attempts = Column(Integer)
    retry_interval = Column(Integer)

    def configure(self):
        from . import models
        # Note: for workflows (operations attached directly to the service) "interface" will be None
        if (self.implementation is None) or (self.interface is None):
            return

        if self.plugin is None:
            arguments = execution_plugin.instantiation.configure_operation(self)
        else:
            # In the future plugins may be able to add their own "configure_operation" hook that
            # can validate the configuration and otherwise return specially derived arguments
            arguments = self.configuration

        # Note: the arguments will *override* operation inputs of the same name
        if arguments:
            for k, v in arguments.iteritems():
                self.inputs[k] = models.Parameter.wrap(k, v)

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('implementation', self.implementation),
            ('dependencies', self.dependencies),
            ('executor', self.executor),
            ('max_attempts', self.max_attempts),
            ('retry_interval', self.retry_interval),
            ('inputs', formatting.as_raw_dict(self.inputs))))

    def validate(self):
        # TODO must be associated with interface or service
        utils.validate_dict_values(self.inputs)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.inputs, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts(context.style.node(self.name))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            if self.plugin is not None:
                console.puts('Plugin: {0}'.format(
                    context.style.literal(self.plugin.name)))
            if self.implementation is not None:
                console.puts('Implementation: {0}'.format(
                    context.style.literal(self.implementation)))
            if self.configuration:
                with context.style.indent:
                    for k, v in self.configuration.iteritems():
                        console.puts('{0}: {1}'.format(context.style.property(k),
                                                       context.style.literal(v)))
            if self.dependencies:
                console.puts(
                    'Dependencies: {0}'.format(
                        ', '.join((str(context.style.literal(v)) for v in self.dependencies))))
            if self.executor is not None:
                console.puts('Executor: {0}'.format(context.style.literal(self.executor)))
            if self.max_attempts is not None:
                console.puts('Max attempts: {0}'.format(context.style.literal(self.max_attempts)))
            if self.retry_interval is not None:
                console.puts('Retry interval: {0}'.format(
                    context.style.literal(self.retry_interval)))
            utils.dump_dict_values(self.inputs, 'Inputs')


class ArtifactBase(InstanceModelMixin):
    """
    A file associated with a :class:`Node`.

    Usually an instance of :class:`ArtifactTemplate`.

    :ivar name: Name (unique for the node)
    :vartype name: basestring
    :ivar artifact_template: Template from which this artifact was instantiated (optional)
    :vartype artifact_template: :class:`ArtifactTemplate`
    :ivar type: Artifact type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: string
    :ivar source_path: Source path (CSAR or repository)
    :vartype source_path: basestring
    :ivar target_path: Path at destination machine
    :vartype target_path: basestring
    :ivar repository_url: Repository URL
    :vartype repository_path: basestring
    :ivar repository_credential: Credentials for accessing the repository
    :vartype repository_credential: {basestring: basestring}
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar node: Containing node
    :vartype node: :class:`Node`
    """

    __tablename__ = 'artifact'

    __private_fields__ = ['type_fk',
                          'node_fk',
                          'artifact_template_fk']

    # region foreign_keys

    @declared_attr
    def type_fk(cls):
        """For Artifact many-to-one to Type"""
        return relationship.foreign_key('type')

    @declared_attr
    def node_fk(cls):
        """For Node one-to-many to Artifact"""
        return relationship.foreign_key('node')

    @declared_attr
    def artifact_template_fk(cls):
        """For Artifact many-to-one to ArtifactTemplate"""
        return relationship.foreign_key('artifact_template', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    # endregion

    # region many_to_one relationships
    @declared_attr
    def node(cls):
        return relationship.many_to_one(cls, 'node')

    @declared_attr
    def artifact_template(cls):
        return relationship.many_to_one(cls, 'artifact_template')

    @declared_attr
    def type(cls):
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
    # endregion

    # region many_to_many relationships
    @declared_attr
    def properties(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='properties', dict_key='name')
    # endregion

    description = Column(Text)
    source_path = Column(Text)
    target_path = Column(Text)
    repository_url = Column(Text)
    repository_credential = Column(modeling_types.StrictDict(basestring, basestring))

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('type_name', self.type.name),
            ('source_path', self.source_path),
            ('target_path', self.target_path),
            ('repository_url', self.repository_url),
            ('repository_credential', formatting.as_agnostic(self.repository_credential)),
            ('properties', formatting.as_raw_dict(self.properties))))

    def validate(self):
        utils.validate_dict_values(self.properties)

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.properties, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts(context.style.node(self.name))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            console.puts('Artifact type: {0}'.format(context.style.type(self.type.name)))
            console.puts('Source path: {0}'.format(context.style.literal(self.source_path)))
            if self.target_path is not None:
                console.puts('Target path: {0}'.format(context.style.literal(self.target_path)))
            if self.repository_url is not None:
                console.puts('Repository URL: {0}'.format(
                    context.style.literal(self.repository_url)))
            if self.repository_credential:
                console.puts('Repository credential: {0}'.format(
                    context.style.literal(self.repository_credential)))
            utils.dump_dict_values(self.properties, 'Properties')
