# 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 __future__ import absolute_import  # so we can import standard 'types'

from datetime import datetime

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

from ..parser import validation
from ..parser.consumption import ConsumptionContext
from ..parser.reading import deepcopy_with_locators
from ..utils import (collections, formatting, console)
from ..utils.versions import VersionString
from .mixins import TemplateModelMixin
from . import (
    relationship,
    utils,
    types as modeling_types
)


class ServiceTemplateBase(TemplateModelMixin):
    """
    A service template is a source for creating :class:`Service` instances.

    It is usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can
    also be created programmatically.

    :ivar name: Name (unique for this ARIA installation)
    :vartype name: basestring
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar main_file_name: Filename of CSAR or YAML file from which this service template was parsed
    :vartype main_file_name: basestring
    :ivar meta_data: Custom annotations
    :vartype meta_data: {basestring: :class:`Metadata`}
    :ivar node_templates: Templates for creating nodes
    :vartype node_templates: {basestring: :class:`NodeTemplate`}
    :ivar group_templates: Templates for creating groups
    :vartype group_templates: {basestring: :class:`GroupTemplate`}
    :ivar policy_templates: Templates for creating policies
    :vartype policy_templates: {basestring: :class:`PolicyTemplate`}
    :ivar substitution_template: The entire service can appear as a node
    :vartype substitution_template: :class:`SubstitutionTemplate`
    :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 workflow_templates: Custom workflows that can be performed on the service
    :vartype workflow_templates: {basestring: :class:`OperationTemplate`}
    :ivar plugin_specifications: Plugins used by the service
    :vartype plugin_specifications: {basestring: :class:`PluginSpecification`}
    :ivar node_types: Base for the node type hierarchy
    :vartype node_types: :class:`Type`
    :ivar group_types: Base for the group type hierarchy
    :vartype group_types: :class:`Type`
    :ivar policy_types: Base for the policy type hierarchy
    :vartype policy_types: :class:`Type`
    :ivar relationship_types: Base for the relationship type hierarchy
    :vartype relationship_types: :class:`Type`
    :ivar capability_types: Base for the capability type hierarchy
    :vartype capability_types: :class:`Type`
    :ivar interface_types: Base for the interface type hierarchy
    :vartype interface_types: :class:`Type`
    :ivar artifact_types: Base for the artifact type hierarchy
    :vartype artifact_types: :class:`Type`
    :ivar created_at: Creation timestamp
    :vartype created_at: :class:`datetime.datetime`
    :ivar updated_at: Update timestamp
    :vartype updated_at: :class:`datetime.datetime`
    :ivar services: Instantiated services
    :vartype services: [:class:`Service`]
    """

    __tablename__ = 'service_template'

    __private_fields__ = ['substitution_template_fk',
                          'node_type_fk',
                          'group_type_fk',
                          'policy_type_fk',
                          'relationship_type_fk',
                          'capability_type_fk',
                          'interface_type_fk',
                          'artifact_type_fk']

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

    # region foreign keys

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

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

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

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

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

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

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

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

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

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

    @declared_attr
    def node_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='node_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def group_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='group_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def policy_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='policy_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def relationship_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='relationship_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def capability_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='capability_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def interface_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='interface_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def artifact_types(cls):
        return relationship.one_to_one(
            cls, 'type', fk='artifact_type_fk', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region one_to_many relationships

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

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

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

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

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

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

    # endregion

    # region many_to_one relationships

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

    # endregion

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('description', self.description),
            ('metadata', formatting.as_raw_dict(self.meta_data)),
            ('node_templates', formatting.as_raw_list(self.node_templates)),
            ('group_templates', formatting.as_raw_list(self.group_templates)),
            ('policy_templates', formatting.as_raw_list(self.policy_templates)),
            ('substitution_template', formatting.as_raw(self.substitution_template)),
            ('inputs', formatting.as_raw_dict(self.inputs)),
            ('outputs', formatting.as_raw_dict(self.outputs)),
            ('workflow_templates', formatting.as_raw_list(self.workflow_templates))))

    @property
    def types_as_raw(self):
        return collections.OrderedDict((
            ('node_types', formatting.as_raw(self.node_types)),
            ('group_types', formatting.as_raw(self.group_types)),
            ('policy_types', formatting.as_raw(self.policy_types)),
            ('relationship_types', formatting.as_raw(self.relationship_types)),
            ('capability_types', formatting.as_raw(self.capability_types)),
            ('interface_types', formatting.as_raw(self.interface_types)),
            ('artifact_types', formatting.as_raw(self.artifact_types))))

    def instantiate(self, container, model_storage, inputs=None):  # pylint: disable=arguments-differ
        from . import models
        context = ConsumptionContext.get_thread_local()
        now = datetime.now()
        service = models.Service(created_at=now,
                                 updated_at=now,
                                 description=deepcopy_with_locators(self.description),
                                 service_template=self)
        context.modeling.instance = service

        service.inputs = utils.create_inputs(inputs or {}, self.inputs)
        # TODO: now that we have inputs, we should scan properties and inputs and evaluate functions

        for plugin_specification in self.plugin_specifications.itervalues():
            if plugin_specification.enabled:
                if plugin_specification.resolve(model_storage):
                    plugin = plugin_specification.plugin
                    service.plugins[plugin.name] = plugin
                else:
                    context = ConsumptionContext.get_thread_local()
                    context.validation.report('specified plugin not found: {0}'.format(
                        plugin_specification.name), level=validation.Issue.EXTERNAL)

        utils.instantiate_dict(self, service.meta_data, self.meta_data)

        for node_template in self.node_templates.itervalues():
            for _ in range(node_template.default_instances):
                node = node_template.instantiate(container)
                service.nodes[node.name] = node

        utils.instantiate_dict(self, service.groups, self.group_templates)
        utils.instantiate_dict(self, service.policies, self.policy_templates)
        utils.instantiate_dict(self, service.workflows, self.workflow_templates)

        if self.substitution_template is not None:
            service.substitution = self.substitution_template.instantiate(container)

        utils.instantiate_dict(self, service.outputs, self.outputs)

        return service

    def validate(self):
        utils.validate_dict_values(self.meta_data)
        utils.validate_dict_values(self.node_templates)
        utils.validate_dict_values(self.group_templates)
        utils.validate_dict_values(self.policy_templates)
        if self.substitution_template is not None:
            self.substitution_template.validate()
        utils.validate_dict_values(self.inputs)
        utils.validate_dict_values(self.outputs)
        utils.validate_dict_values(self.workflow_templates)
        if self.node_types is not None:
            self.node_types.validate()
        if self.group_types is not None:
            self.group_types.validate()
        if self.policy_types is not None:
            self.policy_types.validate()
        if self.relationship_types is not None:
            self.relationship_types.validate()
        if self.capability_types is not None:
            self.capability_types.validate()
        if self.interface_types is not None:
            self.interface_types.validate()
        if self.artifact_types is not None:
            self.artifact_types.validate()

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.meta_data, report_issues)
        utils.coerce_dict_values(self.node_templates, report_issues)
        utils.coerce_dict_values(self.group_templates, report_issues)
        utils.coerce_dict_values(self.policy_templates, report_issues)
        if self.substitution_template is not None:
            self.substitution_template.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.workflow_templates, 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_template in self.node_templates.itervalues():
            node_template.dump()
        for group_template in self.group_templates.itervalues():
            group_template.dump()
        for policy_template in self.policy_templates.itervalues():
            policy_template.dump()
        if self.substitution_template is not None:
            self.substitution_template.dump()
        utils.dump_dict_values(self.inputs, 'Inputs')
        utils.dump_dict_values(self.outputs, 'Outputs')
        utils.dump_dict_values(self.workflow_templates, 'Workflow templates')

    def dump_types(self):
        if self.node_types.children:
            console.puts('Node types:')
            self.node_types.dump()
        if self.group_types.children:
            console.puts('Group types:')
            self.group_types.dump()
        if self.capability_types.children:
            console.puts('Capability types:')
            self.capability_types.dump()
        if self.relationship_types.children:
            console.puts('Relationship types:')
            self.relationship_types.dump()
        if self.policy_types.children:
            console.puts('Policy types:')
            self.policy_types.dump()
        if self.artifact_types.children:
            console.puts('Artifact types:')
            self.artifact_types.dump()
        if self.interface_types.children:
            console.puts('Interface types:')
            self.interface_types.dump()


class NodeTemplateBase(TemplateModelMixin):
    """
    A template for creating zero or more :class:`Node` instances.

    :ivar name: Name (unique for this service template; will usually be used as a prefix for node
                names)
    :vartype name: basestring
    :ivar type: Node type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar default_instances: Default number nodes that will appear in the service
    :vartype default_instances: int
    :ivar min_instances: Minimum number nodes that will appear in the service
    :vartype min_instances: int
    :ivar max_instances: Maximum number nodes that will appear in the service
    :vartype max_instances: int
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interface_templates: Bundles of operations
    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
    :ivar artifact_templates: Associated files
    :vartype artifact_templates: {basestring: :class:`ArtifactTemplate`}
    :ivar capability_templates: Exposed capabilities
    :vartype capability_templates: {basestring: :class:`CapabilityTemplate`}
    :ivar requirement_templates: Potential relationships with other nodes
    :vartype requirement_templates: [:class:`RequirementTemplate`]
    :ivar target_node_template_constraints: Constraints for filtering relationship targets
    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
    :ivar service_template: Containing service template
    :vartype service_template: :class:`ServiceTemplate`
    :ivar group_templates: We are a member of these groups
    :vartype group_templates: [:class:`GroupTemplate`]
    :ivar policy_templates: Policy templates enacted on this node
    :vartype policy_templates: [:class:`PolicyTemplate`]
    :ivar substitution_template_mapping: Our contribution to service substitution
    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
    :ivar nodes: Instantiated nodes
    :vartype nodes: [:class:`Node`]
    """

    __tablename__ = 'node_template'

    __private_fields__ = ['type_fk',
                          'service_template_fk']

    # region foreign_keys

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

    @declared_attr
    def service_template_fk(cls):
        """For ServiceTemplate one-to-many to NodeTemplate"""
        return relationship.foreign_key('service_template')

    # endregion

    # region association proxies

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

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

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

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

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

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

    @declared_attr
    def requirement_templates(cls):
        return relationship.one_to_many(cls, 'requirement_template', child_fk='node_template_fk')

    # endregion

    # region many_to_one relationships

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

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

    # 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)
    default_instances = Column(Integer, default=1)
    min_instances = Column(Integer, default=0)
    max_instances = Column(Integer, default=None)
    target_node_template_constraints = Column(PickleType)

    def is_target_node_template_valid(self, target_node_template):
        if self.target_node_template_constraints:
            for node_template_constraint in self.target_node_template_constraints:
                if not node_template_constraint.matches(self, target_node_template):
                    return False
        return True

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('type_name', self.type.name),
            ('default_instances', self.default_instances),
            ('min_instances', self.min_instances),
            ('max_instances', self.max_instances),
            ('properties', formatting.as_raw_dict(self.properties)),
            ('attributes', formatting.as_raw_dict(self.properties)),
            ('interface_templates', formatting.as_raw_list(self.interface_templates)),
            ('artifact_templates', formatting.as_raw_list(self.artifact_templates)),
            ('capability_templates', formatting.as_raw_list(self.capability_templates)),
            ('requirement_templates', formatting.as_raw_list(self.requirement_templates))))

    def instantiate(self, container):
        from . import models
        if self.nodes:
            highest_name_suffix = max(int(n.name.rsplit('_', 1)[-1]) for n in self.nodes)
            suffix = highest_name_suffix + 1
        else:
            suffix = 1
        name = '{name}_{index}'.format(name=self.name, index=suffix)
        node = models.Node(name=name,
                           type=self.type,
                           description=deepcopy_with_locators(self.description),
                           state=models.Node.INITIAL,
                           runtime_properties={},
                           node_template=self)
        utils.instantiate_dict(node, node.properties, self.properties)
        utils.instantiate_dict(node, node.attributes, self.attributes)
        utils.instantiate_dict(node, node.interfaces, self.interface_templates)
        utils.instantiate_dict(node, node.artifacts, self.artifact_templates)
        utils.instantiate_dict(node, node.capabilities, self.capability_templates)

        # Default attributes
        if 'tosca_name' in node.attributes:
            node.attributes['tosca_name'].value = self.name
        if 'tosca_id' in node.attributes:
            node.attributes['tosca_id'].value = name

        return node

    def validate(self):
        utils.validate_dict_values(self.properties)
        utils.validate_dict_values(self.attributes)
        utils.validate_dict_values(self.interface_templates)
        utils.validate_dict_values(self.artifact_templates)
        utils.validate_dict_values(self.capability_templates)
        utils.validate_list_values(self.requirement_templates)

    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.interface_templates, report_issues)
        utils.coerce_dict_values(self.artifact_templates, report_issues)
        utils.coerce_dict_values(self.capability_templates, report_issues)
        utils.coerce_list_values(self.requirement_templates, report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Node template: {0}'.format(context.style.node(self.name)))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            console.puts('Instances: {0:d} ({1:d}{2})'.format(
                self.default_instances,
                self.min_instances,
                ' to {0:d}'.format(self.max_instances)
                if self.max_instances is not None
                else ' or more'))
            utils.dump_dict_values(self.properties, 'Properties')
            utils.dump_dict_values(self.attributes, 'Attributes')
            utils.dump_interfaces(self.interface_templates)
            utils.dump_dict_values(self.artifact_templates, 'Artifact templates')
            utils.dump_dict_values(self.capability_templates, 'Capability templates')
            utils.dump_list_values(self.requirement_templates, 'Requirement templates')


class GroupTemplateBase(TemplateModelMixin):
    """
    A template for creating a :class:`Group` instance.

    Groups are logical containers for zero or more nodes.

    :ivar name: Name (unique for this service template)
    :vartype name: basestring
    :ivar type: Group type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar node_templates: All nodes instantiated by these templates will be members of the group
    :vartype node_templates: [:class:`NodeTemplate`]
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interface_templates: Bundles of operations
    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
    :ivar service_template: Containing service template
    :vartype service_template: :class:`ServiceTemplate`
    :ivar policy_templates: Policy templates enacted on this group
    :vartype policy_templates: [:class:`PolicyTemplate`]
    :ivar groups: Instantiated groups
    :vartype groups: [:class:`Group`]
    """

    __tablename__ = 'group_template'

    __private_fields__ = ['type_fk',
                          'service_template_fk']

    # region foreign keys

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

    @declared_attr
    def service_template_fk(cls):
        """For ServiceTemplate one-to-many to GroupTemplate"""
        return relationship.foreign_key('service_template')

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

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

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        return relationship.many_to_one(cls, 'service_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 node_templates(cls):
        return relationship.many_to_many(cls, 'node_template')

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

    # endregion

    description = Column(Text)

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

    def instantiate(self, container):
        from . import models
        group = models.Group(name=self.name,
                             type=self.type,
                             description=deepcopy_with_locators(self.description),
                             group_template=self)
        utils.instantiate_dict(self, group.properties, self.properties)
        utils.instantiate_dict(self, group.interfaces, self.interface_templates)
        if self.node_templates:
            for node_template in self.node_templates:
                group.nodes += node_template.nodes
        return group

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

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

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        console.puts('Group template: {0}'.format(context.style.node(self.name)))
        if self.description:
            console.puts(context.style.meta(self.description))
        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.interface_templates)
            if self.node_templates:
                console.puts('Member node templates: {0}'.format(', '.join(
                    (str(context.style.node(v.name)) for v in self.node_templates))))


class PolicyTemplateBase(TemplateModelMixin):
    """
    Policies can be applied to zero or more :class:`NodeTemplate` or :class:`GroupTemplate`
    instances.

    :ivar name: Name (unique for this service template)
    :vartype name: basestring
    :ivar type: Policy type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar node_templates: Policy will be enacted on all nodes instantiated by these templates
    :vartype node_templates: [:class:`NodeTemplate`]
    :ivar group_templates: Policy will be enacted on all nodes in these groups
    :vartype group_templates: [:class:`GroupTemplate`]
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar service_template: Containing service template
    :vartype service_template: :class:`ServiceTemplate`
    :ivar policies: Instantiated policies
    :vartype policies: [:class:`Policy`]
    """

    __tablename__ = 'policy_template'

    __private_fields__ = ['type_fk', 'service_template_fk']

    # region foreign keys

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

    @declared_attr
    def service_template_fk(cls):
        """For ServiceTemplate one-to-many to PolicyTemplate"""
        return relationship.foreign_key('service_template')

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        return relationship.many_to_one(cls, 'service_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 node_templates(cls):
        return relationship.many_to_many(cls, 'node_template')

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

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

    # endregion

    description = Column(Text)

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

    def instantiate(self, container):
        from . import models
        policy = models.Policy(name=self.name,
                               type=self.type,
                               description=deepcopy_with_locators(self.description),
                               policy_template=self)
        utils.instantiate_dict(self, policy.properties, self.properties)
        if self.node_templates:
            for node_template in self.node_templates:
                policy.nodes += node_template.nodes
        if self.group_templates:
            for group_template in self.group_templates:
                policy.groups += group_template.groups
        return policy

    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 template: {0}'.format(context.style.node(self.name)))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            console.puts('Type: {0}'.format(context.style.type(self.type.name)))
            utils.dump_dict_values(self.properties, 'Properties')
            if self.node_templates:
                console.puts('Target node templates: {0}'.format(', '.join(
                    (str(context.style.node(v.name)) for v in self.node_templates))))
            if self.group_templates:
                console.puts('Target group templates: {0}'.format(', '.join(
                    (str(context.style.node(v.name)) for v in self.group_templates))))


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

    :ivar node_type: Exposed node type
    :vartype node_type: :class:`Type`
    :ivar mappings: Requirement and capability mappings
    :vartype mappings: {basestring: :class:`SubstitutionTemplateMapping`}
    :ivar service_template: Containing service template
    :vartype service_template: :class:`ServiceTemplate`
    :ivar substitutions: Instantiated substitutions
    :vartype substitutions: [:class:`Substitution`]
    """

    __tablename__ = 'substitution_template'

    __private_fields__ = ['node_type_fk']

    # region foreign keys

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

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def substitutions(cls):
        return relationship.one_to_many(cls, 'substitution')

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

    # endregion

    # region many_to_one relationships

    @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 instantiate(self, container):
        from . import models
        substitution = models.Substitution(node_type=self.node_type,
                                           substitution_template=self)
        utils.instantiate_dict(container, substitution.mappings, self.mappings)
        return substitution

    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 template:')
        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 SubstitutionTemplateMappingBase(TemplateModelMixin):
    """
    Used by :class:`SubstitutionTemplate` to map a capability or a requirement to a node.

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

    :ivar name: Exposed capability or requirement name
    :vartype name: basestring
    :ivar node_template: Node template
    :vartype node_template: :class:`NodeTemplate`
    :ivar capability_template: Capability template in the node template
    :vartype capability_template: :class:`CapabilityTemplate`
    :ivar requirement_template: Requirement template in the node template
    :vartype requirement_template: :class:`RequirementTemplate`
    :ivar substitution_template: Containing substitution template
    :vartype substitution_template: :class:`SubstitutionTemplate`
    """

    __tablename__ = 'substitution_template_mapping'

    __private_fields__ = ['substitution_template_fk',
                          'node_template_fk',
                          'capability_template_fk',
                          'requirement_template_fk']

    # region foreign keys

    @declared_attr
    def substitution_template_fk(cls):
        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
        return relationship.foreign_key('substitution_template')

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

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

    @declared_attr
    def requirement_template_fk(cls):
        """For SubstitutionTemplate 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 node_template(cls):
        return relationship.one_to_one(
            cls, 'node_template', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def capability_template(cls):
        return relationship.one_to_one(
            cls, 'capability_template', 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

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

    # 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 instantiate(self, container):
        from . import models
        context = ConsumptionContext.get_thread_local()
        nodes = self.node_template.nodes
        if len(nodes) == 0:
            context.validation.report(
                'mapping "{0}" refers to node template "{1}" but there are no '
                'node instances'.format(self.mapped_name, self.node_template.name),
                level=validation.Issue.BETWEEN_INSTANCES)
            return None
        # The TOSCA spec does not provide a way to choose the node,
        # so we will just pick the first one
        node = nodes[0]
        capability = None
        if self.capability_template:
            for a_capability in node.capabilities.itervalues():
                if a_capability.capability_template.name == self.capability_template.name:
                    capability = a_capability
        return models.SubstitutionMapping(name=self.name,
                                          node=node,
                                          capability=capability,
                                          requirement_template=self.requirement_template)

    def validate(self):
        context = ConsumptionContext.get_thread_local()
        if (self.capability_template is None) and (self.requirement_template is None):
            context.validation.report('mapping "{0}" refers to neither capability nor a requirement'
                                      ' in node template: {1}'.format(
                                          self.name,
                                          formatting.safe_repr(self.node_template.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_template.name),
            context.style.node(self.capability_template.name
                               if self.capability_template
                               else self.requirement_template.name)))


class RequirementTemplateBase(TemplateModelMixin):
    """
    A requirement for a :class:`NodeTemplate`. During instantiation will be matched with a
    capability of another node.

    Requirements may optionally contain a :class:`RelationshipTemplate` that will be created between
    the nodes.

    :ivar name: Name (a node template can have multiple requirements with the same name)
    :vartype name: basestring
    :ivar target_node_type: Required node type (optional)
    :vartype target_node_type: :class:`Type`
    :ivar target_node_template: Required node template (optional)
    :vartype target_node_template: :class:`NodeTemplate`
    :ivar target_capability_type: Required capability type (optional)
    :vartype target_capability_type: :class:`Type`
    :ivar target_capability_name: Name of capability in target node (optional)
    :vartype target_capability_name: basestring
    :ivar target_node_template_constraints: Constraints for filtering relationship targets
    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
    :ivar relationship_template: Template for relationships (optional)
    :vartype relationship_template: :class:`RelationshipTemplate`
    :ivar node_template: Containing node template
    :vartype node_template: :class:`NodeTemplate`
    :ivar substitution_template_mapping: Our contribution to service substitution
    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
    :ivar substitution_mapping: Our contribution to service substitution
    :vartype substitution_mapping: :class:`SubstitutionMapping`
    """

    __tablename__ = 'requirement_template'

    __private_fields__ = ['target_node_type_fk',
                          'target_node_template_fk',
                          'target_capability_type_fk'
                          'node_template_fk',
                          'relationship_template_fk']

    # region foreign keys

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

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

    @declared_attr
    def target_capability_type_fk(cls):
        """For RequirementTemplate one-to-one to NodeTemplate"""
        return relationship.foreign_key('type', nullable=True)

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

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

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def target_node_template(cls):
        return relationship.one_to_one(cls,
                                       'node_template',
                                       fk='target_node_template_fk',
                                       back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def target_capability_type(cls):
        return relationship.one_to_one(cls,
                                       'type',
                                       fk='target_capability_type_fk',
                                       back_populates=relationship.NO_BACK_POP)

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

    # endregion

    # region one_to_many relationships

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

    # endregion

    # region many_to_one relationships

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

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

    # endregion

    # region many_to_many relationships

    # endregion

    target_capability_name = Column(Text)
    target_node_template_constraints = Column(PickleType)

    def find_target(self, source_node_template):
        context = ConsumptionContext.get_thread_local()

        # We might already have a specific node template, so we'll just verify it
        if self.target_node_template is not None:
            if not source_node_template.is_target_node_template_valid(self.target_node_template):
                context.validation.report('requirement "{0}" of node template "{1}" is for node '
                                          'template "{2}" but it does not match constraints'.format(
                                              self.name,
                                              self.target_node_template.name,
                                              source_node_template.name),
                                          level=validation.Issue.BETWEEN_TYPES)
            if (self.target_capability_type is not None) \
                or (self.target_capability_name is not None):
                target_node_capability = self.find_target_capability(source_node_template,
                                                                     self.target_node_template)
                if target_node_capability is None:
                    return None, None
            else:
                target_node_capability = None

            return self.target_node_template, target_node_capability

        # Find first node that matches the type
        elif self.target_node_type is not None:
            for target_node_template in \
                    self.node_template.service_template.node_templates.values():
                if self.target_node_type.get_descendant(target_node_template.type.name) is None:
                    continue

                if not source_node_template.is_target_node_template_valid(target_node_template):
                    continue

                target_node_capability = self.find_target_capability(source_node_template,
                                                                     target_node_template)
                if target_node_capability is None:
                    continue

                return target_node_template, target_node_capability

        return None, None

    def find_target_capability(self, source_node_template, target_node_template):
        for capability_template in target_node_template.capability_templates.itervalues():
            if capability_template.satisfies_requirement(source_node_template,
                                                         self,
                                                         target_node_template):
                return capability_template
        return None

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('target_node_type_name', self.target_node_type.name
             if self.target_node_type is not None else None),
            ('target_node_template_name', self.target_node_template.name
             if self.target_node_template is not None else None),
            ('target_capability_type_name', self.target_capability_type.name
             if self.target_capability_type is not None else None),
            ('target_capability_name', self.target_capability_name),
            ('relationship_template', formatting.as_raw(self.relationship_template))))

    def validate(self):
        if self.relationship_template:
            self.relationship_template.validate()

    def coerce_values(self, report_issues):
        if self.relationship_template is not None:
            self.relationship_template.coerce_values(report_issues)

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        if self.name:
            console.puts(context.style.node(self.name))
        else:
            console.puts('Requirement:')
        with context.style.indent:
            if self.target_node_type is not None:
                console.puts('Target node type: {0}'.format(
                    context.style.type(self.target_node_type.name)))
            elif self.target_node_template is not None:
                console.puts('Target node template: {0}'.format(
                    context.style.node(self.target_node_template.name)))
            if self.target_capability_type is not None:
                console.puts('Target capability type: {0}'.format(
                    context.style.type(self.target_capability_type.name)))
            elif self.target_capability_name is not None:
                console.puts('Target capability name: {0}'.format(
                    context.style.node(self.target_capability_name)))
            if self.target_node_template_constraints:
                console.puts('Target node template constraints:')
                with context.style.indent:
                    for constraint in self.target_node_template_constraints:
                        console.puts(context.style.literal(constraint))
            if self.relationship_template:
                console.puts('Relationship:')
                with context.style.indent:
                    self.relationship_template.dump()


class RelationshipTemplateBase(TemplateModelMixin):
    """
    Optional addition to a :class:`RequirementTemplate` in :class:`NodeTemplate` that can be applied
    when the requirement is matched with a capability.

    Note that a relationship template here is not equivalent to a relationship template entity in
    TOSCA. For example, a TOSCA requirement specifying a relationship type instead of a template
    would still be represented here as a relationship template.

    :ivar name: Name (optional; if present is unique for this service template)
    :vartype name: basestring
    :ivar type: Relationship type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar interface_templates: Bundles of operations
    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
    :ivar requirement_template: Containing requirement template
    :vartype requirement_template: :class:`RequirementTemplate`
    :ivar relationships: Instantiated relationships
    :vartype relationships: [:class:`Relationship`]
    """

    __tablename__ = 'relationship_template'

    __private_fields__ = ['type_fk']

    # region foreign keys

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

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

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

    # endregion

    # region many_to_one relationships

    @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)

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('type_name', self.type.name if self.type is not None else None),
            ('name', self.name),
            ('description', self.description),
            ('properties', formatting.as_raw_dict(self.properties)),
            ('interface_templates', formatting.as_raw_list(self.interface_templates))))

    def instantiate(self, container):
        from . import models
        relationship_model = models.Relationship(name=self.name,
                                                 type=self.type,
                                                 relationship_template=self)
        utils.instantiate_dict(container, relationship_model.properties, self.properties)
        utils.instantiate_dict(container, relationship_model.interfaces, self.interface_templates)
        return relationship_model

    def validate(self):
        # TODO: either type or name must be set
        utils.validate_dict_values(self.properties)
        utils.validate_dict_values(self.interface_templates)

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

    def dump(self):
        context = ConsumptionContext.get_thread_local()
        if self.type is not None:
            console.puts('Relationship type: {0}'.format(context.style.type(self.type.name)))
        else:
            console.puts('Relationship template: {0}'.format(
                context.style.node(self.name)))
        if self.description:
            console.puts(context.style.meta(self.description))
        with context.style.indent:
            utils.dump_dict_values(self.properties, 'Properties')
            utils.dump_interfaces(self.interface_templates, 'Interface templates')


class CapabilityTemplateBase(TemplateModelMixin):
    """
    A capability of a :class:`NodeTemplate`. Nodes expose zero or more capabilities that can be
    matched with :class:`Requirement` instances of other nodes.

    :ivar name: Name (unique for the node template)
    :vartype name: basestring
    :ivar type: Capability type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar valid_source_node_types: Reject requirements that are not from these node types (optional)
    :vartype valid_source_node_types: [: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 properties: Associated parameters
    :vartype properties: {basestring: :class:`Parameter`}
    :ivar node_template: Containing node template
    :vartype node_template: :class:`NodeTemplate`
    :ivar substitution_template_mapping: Our contribution to service substitution
    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
    :ivar capabilities: Instantiated capabilities
    :vartype capabilities: [:class:`Capability`]
    """

    __tablename__ = 'capability_template'

    __private_fields__ = ['type_fk',
                          'node_template_fk']

    # region foreign keys

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

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

    # endregion


    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

    # endregion

    # region many_to_one relationships

    @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 valid_source_node_types(cls):
        return relationship.many_to_many(cls, 'type', prefix='valid_sources')

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

    # endregion

    description = Column(Text)
    min_occurrences = Column(Integer, default=None)  # optional
    max_occurrences = Column(Integer, default=None)  # optional

    def satisfies_requirement(self,
                              source_node_template,
                              requirement,
                              target_node_template):
        # Do we match the required capability type?
        if requirement.target_capability_type and \
            requirement.target_capability_type.get_descendant(self.type.name) is None:
            return False

        # Are we in valid_source_node_types?
        if self.valid_source_node_types:
            for valid_source_node_type in self.valid_source_node_types:
                if valid_source_node_type.get_descendant(source_node_template.type.name) is None:
                    return False

        # Apply requirement constraints
        if requirement.target_node_template_constraints:
            for node_template_constraint in requirement.target_node_template_constraints:
                if not node_template_constraint.matches(source_node_template, target_node_template):
                    return False

        return True

    @property
    def as_raw(self):
        return collections.OrderedDict((
            ('name', self.name),
            ('description', self.description),
            ('type_name', self.type.name),
            ('min_occurrences', self.min_occurrences),
            ('max_occurrences', self.max_occurrences),
            ('valid_source_node_types', [v.name for v in self.valid_source_node_types]),
            ('properties', formatting.as_raw_dict(self.properties))))

    def instantiate(self, container):
        from . import models
        capability = models.Capability(name=self.name,
                                       type=self.type,
                                       min_occurrences=self.min_occurrences,
                                       max_occurrences=self.max_occurrences,
                                       occurrences=0,
                                       capability_template=self)
        utils.instantiate_dict(container, capability.properties, self.properties)
        return capability

    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('Type: {0}'.format(context.style.type(self.type.name)))
            console.puts(
                'Occurrences: {0:d}{1}'.format(
                    self.min_occurrences or 0,
                    ' to {0:d}'.format(self.max_occurrences)
                    if self.max_occurrences is not None
                    else ' or more'))
            if self.valid_source_node_types:
                console.puts('Valid source node types: {0}'.format(
                    ', '.join((str(context.style.type(v.name))
                               for v in self.valid_source_node_types))))
            utils.dump_dict_values(self.properties, 'Properties')


class InterfaceTemplateBase(TemplateModelMixin):
    """
    A typed set of :class:`OperationTemplate`.

    :ivar name: Name (unique for the node, group, or relationship template)
    :vartype name: basestring
    :ivar type: Interface type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar inputs: Parameters that can be used by all operations in the interface
    :vartype inputs: {basestring: :class:`Parameter`}
    :ivar operation_templates: Operations
    :vartype operation_templates: {basestring: :class:`OperationTemplate`}
    :ivar node_template: Containing node template
    :vartype node_template: :class:`NodeTemplate`
    :ivar group_template: Containing group template
    :vartype group_template: :class:`GroupTemplate`
    :ivar relationship_template: Containing relationship template
    :vartype relationship_template: :class:`RelationshipTemplate`
    :ivar interfaces: Instantiated interfaces
    :vartype interfaces: [:class:`Interface`]
    """

    __tablename__ = 'interface_template'

    __private_fields__ = ['type_fk',
                          'node_template_fk',
                          'group_template_fk',
                          'relationship_template_fk']


    # region foreign keys

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

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

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

    @declared_attr
    def relationship_template_fk(cls):
        """For RelationshipTemplate one-to-many to InterfaceTemplate"""
        return relationship.foreign_key('relationship_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')

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

    # endregion

    # region many_to_one relationships

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

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

    @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 inputs(cls):
        return relationship.many_to_many(cls, 'parameter', prefix='inputs', dict_key='name')

    # endregion

    description = Column(Text)

    @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)),  # pylint: disable=no-member
            # TODO fix self.properties reference
            ('operation_templates', formatting.as_raw_list(self.operation_templates))))

    def instantiate(self, container):
        from . import models
        interface = models.Interface(name=self.name,
                                     type=self.type,
                                     description=deepcopy_with_locators(self.description),
                                     interface_template=self)
        utils.instantiate_dict(container, interface.inputs, self.inputs)
        utils.instantiate_dict(container, interface.operations, self.operation_templates)
        return interface

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

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.inputs, report_issues)
        utils.coerce_dict_values(self.operation_templates, 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.operation_templates, 'Operation templates')


class OperationTemplateBase(TemplateModelMixin):
    """
    An operation in a :class:`InterfaceTemplate`.

    Operations are executed by an associated :class:`PluginSpecification` via an executor.

    :ivar name: Name (unique for the interface or service template)
    :vartype name: basestring
    :ivar description: Human-readable description
    :vartype description: basestring
    :ivar plugin_specification: Associated plugin
    :vartype plugin_specification: :class:`PluginSpecification`
    :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_template: Containing interface template
    :vartype interface_template: :class:`InterfaceTemplate`
    :ivar service_template: Containing service template
    :vartype service_template: :class:`ServiceTemplate`
    :ivar operations: Instantiated operations
    :vartype operations: [:class:`Operation`]
    """

    __tablename__ = 'operation_template'

    __private_fields__ = ['service_template_fk',
                          'interface_template_fk',
                          'plugin_fk']

    # region foreign keys

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

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

    @declared_attr
    def plugin_specification_fk(cls):
        """For OperationTemplate one-to-one to PluginSpecification"""
        return relationship.foreign_key('plugin_specification', nullable=True)

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

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

    # endregion

    # region one_to_many relationships

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

    # endregion

    # region many_to_one relationships

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

    @declared_attr
    def interface_template(cls):
        return relationship.many_to_one(cls, 'interface_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)

    @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 instantiate(self, container):
        from . import models
        if self.plugin_specification:
            if self.plugin_specification.enabled:
                plugin = self.plugin_specification.plugin
                implementation = self.implementation if plugin is not None else None
                # "plugin" would be none if a match was not found. In that case, a validation error
                # should already have been reported in ServiceTemplateBase.instantiate, so we will
                # continue silently here
            else:
                # If the plugin is disabled, the operation should be disabled, too
                plugin = None
                implementation = None
        else:
            # Using the execution plugin
            plugin = None
            implementation = self.implementation

        operation = models.Operation(name=self.name,
                                     description=deepcopy_with_locators(self.description),
                                     relationship_edge=self.relationship_edge,
                                     plugin=plugin,
                                     implementation=implementation,
                                     configuration=self.configuration,
                                     dependencies=self.dependencies,
                                     executor=self.executor,
                                     max_attempts=self.max_attempts,
                                     retry_interval=self.retry_interval,
                                     operation_template=self)
        utils.instantiate_dict(container, operation.inputs, self.inputs)
        return operation

    def validate(self):
        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_specification is not None:
                console.puts('Plugin specification: {0}'.format(
                    context.style.literal(self.plugin_specification.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 ArtifactTemplateBase(TemplateModelMixin):
    """
    A file associated with a :class:`NodeTemplate`.

    :ivar name: Name (unique for the node template)
    :vartype name: basestring
    :ivar type: Artifact type
    :vartype type: :class:`Type`
    :ivar description: Human-readable description
    :vartype description: basestring
    :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_template: Containing node template
    :vartype node_template: :class:`NodeTemplate`
    :ivar artifacts: Instantiated artifacts
    :vartype artifacts: [:class:`Artifact`]
    """

    __tablename__ = 'artifact_template'

    __private_fields__ = ['type_fk',
                          'node_template_fk']

    # region foreign keys

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

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

    # endregion

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

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

    # endregion

    # region many_to_one relationships

    @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')

    # 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 instantiate(self, container):
        from . import models
        artifact = models.Artifact(name=self.name,
                                   type=self.type,
                                   description=deepcopy_with_locators(self.description),
                                   source_path=self.source_path,
                                   target_path=self.target_path,
                                   repository_url=self.repository_url,
                                   repository_credential=self.repository_credential,
                                   artifact_template=self)
        utils.instantiate_dict(container, artifact.properties, self.properties)
        return artifact

    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')


class PluginSpecificationBase(TemplateModelMixin):
    """
    Plugin specification.

    :ivar name: Required plugin name
    :vartype name: basestring
    :ivar version: Minimum plugin version
    :vartype version: basestring
    :ivar enabled: Whether the plugin is enabled
    :vartype enabled: bool
    :ivar plugin: The matching plugin (or None if not matched)
    :vartype plugin: :class:`Plugin`
    """

    __tablename__ = 'plugin_specification'

    __private_fields__ = ['service_template_fk',
                          'plugin_fk']

    version = Column(Text)
    enabled = Column(Boolean, nullable=False, default=True)

    # region foreign keys

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

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

    # endregion

    # region many_to_one relationships

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

    @declared_attr
    def plugin(cls): # pylint: disable=method-hidden
        return relationship.many_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)

    # endregion

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

    def coerce_values(self, report_issues):
        pass

    def resolve(self, model_storage):
        # TODO: we are planning a separate "instantiation" module where this will be called or
        # moved to.
        plugins = model_storage.plugin.list()
        matching_plugins = []
        if plugins:
            for plugin in plugins:
                if (plugin.name == self.name) and \
                    ((self.version is None) or \
                     (VersionString(plugin.package_version) >= self.version)):
                    matching_plugins.append(plugin)
        self.plugin = None
        if matching_plugins:
            # Return highest version of plugin
            key = lambda plugin: VersionString(plugin.package_version).key
            self.plugin = sorted(matching_plugins, key=key)[-1]
        return self.plugin is not None
