# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
ARIA modeling service template module
"""

# 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 ..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):
    """
    Template for creating :class:`Service` instances.

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

    __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, doc="""
    Human-readable description.

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

    main_file_name = Column(Text, doc="""
    Filename of CSAR or YAML file from which this service template was parsed.
    
    :type: :obj:`basestring`
    """)

    created_at = Column(DateTime, nullable=False, index=True, doc="""
    Creation timestamp.

    :type: :class:`~datetime.datetime`
    """)

    updated_at = Column(DateTime, doc="""
    Update timestamp.

    :type: :class:`~datetime.datetime`
    """)

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def substitution_template(cls):
        """
        Exposes an entire service as a single node.

        :type: :class:`SubstitutionTemplate`
        """
        return relationship.one_to_one(
            cls, 'substitution_template', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def node_types(cls):
        """
        Base for the node type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='node_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def group_types(cls):
        """
        Base for the group type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='group_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def policy_types(cls):
        """
        Base for the policy type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='policy_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def relationship_types(cls):
        """
        Base for the relationship type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='relationship_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def capability_types(cls):
        """
        Base for the capability type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='capability_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def interface_types(cls):
        """
        Base for the interface type hierarchy,

        :type: :class:`Type`
        """
        return relationship.one_to_one(
            cls, 'type', fk='interface_type_fk', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def artifact_types(cls):
        """
        Base for the artifact type hierarchy,

        :type: :class:`Type`
        """
        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):
        """
        Instantiated services.

        :type: [:class:`Service`]
        """
        return relationship.one_to_many(cls, 'service', dict_key='name')

    @declared_attr
    def node_templates(cls):
        """
        Templates for creating nodes.

        :type: {:obj:`basestring`, :class:`NodeTemplate`}
        """
        return relationship.one_to_many(cls, 'node_template', dict_key='name')

    @declared_attr
    def group_templates(cls):
        """
        Templates for creating groups.

        :type: {:obj:`basestring`, :class:`GroupTemplate`}
        """
        return relationship.one_to_many(cls, 'group_template', dict_key='name')

    @declared_attr
    def policy_templates(cls):
        """
        Templates for creating policies.

        :type: {:obj:`basestring`, :class:`PolicyTemplate`}
        """
        return relationship.one_to_many(cls, 'policy_template', dict_key='name')

    @declared_attr
    def workflow_templates(cls):
        """
        Templates for creating workflows.

        :type: {:obj:`basestring`, :class:`OperationTemplate`}
        """
        return relationship.one_to_many(cls, 'operation_template', dict_key='name')

    @declared_attr
    def outputs(cls):
        """
        Declarations for output parameters are filled in after service installation.

        :type: {:obj:`basestring`: :class:`Output`}
        """
        return relationship.one_to_many(cls, 'output', dict_key='name')

    @declared_attr
    def inputs(cls):
        """
        Declarations for externally provided parameters.

        :type: {:obj:`basestring`: :class:`Input`}
        """
        return relationship.one_to_many(cls, 'input', dict_key='name')

    @declared_attr
    def plugin_specifications(cls):
        """
        Required plugins for instantiated services.

        :type: {:obj:`basestring`: :class:`PluginSpecification`}
        """
        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):
        """
        Associated metadata.

        :type: {:obj:`basestring`: :class:`Metadata`}
        """
        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
        return relationship.many_to_many(cls, 'metadata', dict_key='name')

    # endregion

    # 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

    @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.merge_parameter_values(inputs, self.inputs, model_cls=models.Input)
        # 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):
    """
    Template for creating zero or more :class:`Node` instances, which are typed vertices in the
    service topology.
    """

    __tablename__ = 'node_template'

    __private_fields__ = ('type_fk',
                          'service_template_fk')

    # region association proxies

    @declared_attr
    def service_template_name(cls):
        return relationship.association_proxy('service_template', 'name')

    @declared_attr
    def type_name(cls):
        return relationship.association_proxy('type', 'name')

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def nodes(cls):
        """
        Instantiated nodes.

        :type: [:class:`Node`]
        """
        return relationship.one_to_many(cls, 'node')

    @declared_attr
    def interface_templates(cls):
        """
        Associated interface templates.

        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
        """
        return relationship.one_to_many(cls, 'interface_template', dict_key='name')

    @declared_attr
    def artifact_templates(cls):
        """
        Associated artifacts.

        :type: {:obj:`basestring`: :class:`ArtifactTemplate`}
        """
        return relationship.one_to_many(cls, 'artifact_template', dict_key='name')

    @declared_attr
    def capability_templates(cls):
        """
        Associated exposed capability templates.

        :type: {:obj:`basestring`: :class:`CapabilityTemplate`}
        """
        return relationship.one_to_many(cls, 'capability_template', dict_key='name')

    @declared_attr
    def requirement_templates(cls):
        """
        Associated potential relationships with other nodes.

        :type: [:class:`RequirementTemplate`]
        """
        return relationship.one_to_many(cls, 'requirement_template', other_fk='node_template_fk')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    @declared_attr
    def attributes(cls):
        """
        Declarations for associated mutable parameters.

        :type: {:obj:`basestring`: :class:`Attribute`}
        """
        return relationship.one_to_many(cls, 'attribute', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def type(cls):
        """
        Node type.

        :type: :class:`Type`
        """
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def service_template(cls):
        """
        Containing service template.

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

    # endregion

    # 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

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

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

    default_instances = Column(Integer, default=1, doc="""
    Default number nodes that will appear in the service.

    :type: :obj:`int`
    """)

    min_instances = Column(Integer, default=0, doc="""
    Minimum number nodes that will appear in the service.

    :type: :obj:`int`
    """)

    max_instances = Column(Integer, default=None, doc="""
    Maximum number nodes that will appear in the service.

    :type: :obj:`int`
    """)

    target_node_template_constraints = Column(PickleType, doc="""
    Constraints for filtering relationship targets.

    :type: [:class:`NodeTemplateConstraint`]
    """)

    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,
                           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):
    """
    Template for creating a :class:`Group` instance, which is a typed logical container for zero or
    more :class:`Node` instances.
    """

    __tablename__ = 'group_template'

    __private_fields__ = ('type_fk',
                          'service_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def groups(cls):
        """
        Instantiated groups.

        :type: [:class:`Group`]
        """
        return relationship.one_to_many(cls, 'group')

    @declared_attr
    def interface_templates(cls):
        """
        Associated interface templates.

        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
        """
        return relationship.one_to_many(cls, 'interface_template', dict_key='name')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        """
        Containing service template.

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

    @declared_attr
    def type(cls):
        """
        Group type.

        :type: :class:`Type`
        """
        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):
        """
        Nodes instantiated by these templates will be members of the group.

        :type: [:class:`NodeTemplate`]
        """
        return relationship.many_to_many(cls, 'node_template')

    # endregion

    # 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

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

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

    @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):
    """
    Template for creating a :class:`Policy` instance, which is a typed set of orchestration hints
    applied to zero or more :class:`Node` or :class:`Group` instances.
    """

    __tablename__ = 'policy_template'

    __private_fields__ = ('type_fk',
                          'service_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def policies(cls):
        """
        Instantiated policies.

        :type: [:class:`Policy`]
        """
        return relationship.one_to_many(cls, 'policy')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        """
        Containing service template.

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

    @declared_attr
    def type(cls):
        """
        Policy type.

        :type: :class:`Type`
        """
        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):
        """
        Policy will be enacted on all nodes instantiated by these templates.

        :type: {:obj:`basestring`: :class:`NodeTemplate`}
        """
        return relationship.many_to_many(cls, 'node_template')

    @declared_attr
    def group_templates(cls):
        """
        Policy will be enacted on all nodes in all groups instantiated by these templates.

        :type: {:obj:`basestring`: :class:`GroupTemplate`}
        """
        return relationship.many_to_many(cls, 'group_template')

    # endregion

    # 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

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

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

    @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):
    """
    Template for creating a :class:`Substitution` instance, which exposes an entire instantiated
    service as a single node.
    """

    __tablename__ = 'substitution_template'

    __private_fields__ = ('node_type_fk',)

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def substitutions(cls):
        """
        Instantiated substitutions.

        :type: [:class:`Substitution`]
        """
        return relationship.one_to_many(cls, 'substitution')

    @declared_attr
    def mappings(cls):
        """
        Map requirement and capabilities to exposed node.

        :type: {:obj:`basestring`: :class:`SubstitutionTemplateMapping`}
        """
        return relationship.one_to_many(cls, 'substitution_template_mapping', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node_type(cls):
        """
        Exposed node type.

        :type: :class:`Type`
        """
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region foreign keys

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

    # 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 template or a requirement template to
    the exposed node.

    The :attr:`name` field should match the capability or requirement name on the exposed node's
    type.

    Only one of :attr:`capability_template` and :attr:`requirement_template` can be set.
    """

    __tablename__ = 'substitution_template_mapping'

    __private_fields__ = ('substitution_template_fk',
                          'capability_template_fk',
                          'requirement_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def capability_template(cls):
        """
        Capability template to expose (can be ``None``).

        :type: :class:`CapabilityTemplate`
        """
        return relationship.one_to_one(
            cls, 'capability_template', back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def requirement_template(cls):
        """
        Requirement template to expose (can be ``None``).

        :type: :class:`RequirementTemplate`
        """
        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):
        """
        Containing substitution template.

        :type: :class:`SubstitutionTemplate`
        """
        return relationship.many_to_one(cls, 'substitution_template', back_populates='mappings')

    # endregion

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

    @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()
        if self.capability_template is not None:
            node_template = self.capability_template.node_template
        else:
            node_template = self.requirement_template.node_template
        nodes = 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,
                                          capability=capability,
                                          requirement_template=self.requirement_template,
                                          node=node)


    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()
        if self.capability_template is not None:
            node_template = self.capability_template.node_template
        else:
            node_template = self.requirement_template.node_template
        console.puts('{0} -> {1}.{2}'.format(
            context.style.node(self.name),
            context.style.node(node_template.name),
            context.style.node(self.capability_template.name
                               if self.capability_template
                               else self.requirement_template.name)))


class RequirementTemplateBase(TemplateModelMixin):
    """
    Template for creating :class:`Relationship` instances, which are optionally-typed edges in the
    service topology, connecting a :class:`Node` to a :class:`Capability` of another node.

    Note that there is no equivalent "Requirement" instance model. Instead, during instantiation a
    requirement template is matched with a capability and a :class:`Relationship` is instantiated.

    A requirement template *must* target a :class:`CapabilityType` or a capability name. It can
    optionally target a specific :class:`NodeType` or :class:`NodeTemplate`.

    Requirement templates may optionally contain a :class:`RelationshipTemplate`. If they do not,
    a :class:`Relationship` will be instantiated with default values.
    """

    __tablename__ = 'requirement_template'

    __private_fields__ = ('target_capability_type_fk',
                          'target_node_template_fk',
                          'target_node_type_fk',
                          'relationship_template_fk',
                          'node_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def target_capability_type(cls):
        """
        Target capability type.

        :type: :class:`CapabilityType`
        """
        return relationship.one_to_one(cls,
                                       'type',
                                       fk='target_capability_type_fk',
                                       back_populates=relationship.NO_BACK_POP)

    @declared_attr
    def target_node_template(cls):
        """
        Target node template (can be ``None``).

        :type: :class:`NodeTemplate`
        """
        return relationship.one_to_one(cls,
                                       'node_template',
                                       fk='target_node_template_fk',
                                       back_populates=relationship.NO_BACK_POP)

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

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

    # endregion

    # region one_to_many relationships

    @declared_attr
    def relationships(cls):
        """
        Instantiated relationships.

        :type: [:class:`Relationship`]
        """
        return relationship.one_to_many(cls, 'relationship')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node_template(cls):
        """
        Containing node template.

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

    @declared_attr
    def target_node_type(cls):
        """
        Target node type (can be ``None``).

        :type: :class:`Type`
        """
        return relationship.many_to_one(
            cls, 'type', fk='target_node_type_fk', back_populates=relationship.NO_BACK_POP)

    # endregion

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

    target_capability_name = Column(Text, doc="""
    Target capability name in node template or node type (can be ``None``).

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

    target_node_template_constraints = Column(PickleType, doc="""
    Constraints for filtering relationship targets.

    :type: [:class:`NodeTemplateConstraint`]
    """)

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

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

    __tablename__ = 'relationship_template'

    __private_fields__ = ('type_fk',)

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def relationships(cls):
        """
        Instantiated relationships.

        :type: [:class:`Relationship`]
        """
        return relationship.one_to_many(cls, 'relationship')

    @declared_attr
    def interface_templates(cls):
        """
        Associated interface templates.

        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
        """
        return relationship.one_to_many(cls, 'interface_template', dict_key='name')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def type(cls):
        """
        Relationship type.

        :type: :class:`Type`
        """
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # region foreign keys

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

    # endregion

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

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

    @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):
    """
    Template for creating :class:`Capability` instances, typed attachments which serve two purposes:
    to provide extra properties and attributes to :class:`Node` instances, and to expose targets for
    :class:`Relationship` instances from other nodes.
    """

    __tablename__ = 'capability_template'

    __private_fields__ = ('type_fk',
                          'node_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def capabilities(cls):
        """
        Instantiated capabilities.

        :type: [:class:`Capability`]
        """
        return relationship.one_to_many(cls, 'capability')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node_template(cls):
        """
        Containing node template.

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

    @declared_attr
    def type(cls):
        """
        Capability type.

        :type: :class:`Type`
        """
        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):
        """
        Reject requirements that are not from these node types.

        :type: [:class:`Type`]
        """
        return relationship.many_to_many(cls, 'type', prefix='valid_sources')

    # endregion

    # 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

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

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

    min_occurrences = Column(Integer, default=None, doc="""
    Minimum number of requirement matches required.

    :type: :obj:`int`
    """)

    max_occurrences = Column(Integer, default=None, doc="""
    Maximum number of requirement matches allowed.

    :type: :obj:`int`
    """)

    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):
    """
    Template for creating :class:`Interface` instances, which are typed bundles of
    :class:`Operation` instances.

    Can be associated with a :class:`NodeTemplate`, a :class:`GroupTemplate`, or a
    :class:`RelationshipTemplate`.
    """

    __tablename__ = 'interface_template'

    __private_fields__ = ('type_fk',
                          'node_template_fk',
                          'group_template_fk',
                          'relationship_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def inputs(cls):
        """
        Declarations for externally provided parameters that can be used by all operations of the
        interface.

        :type: {:obj:`basestring`: :class:`Input`}
        """
        return relationship.one_to_many(cls, 'input', dict_key='name')

    @declared_attr
    def interfaces(cls):
        """
        Instantiated interfaces.

        :type: [:class:`Interface`]
        """
        return relationship.one_to_many(cls, 'interface')

    @declared_attr
    def operation_templates(cls):
        """
        Associated operation templates.

        :type: {:obj:`basestring`: :class:`OperationTemplate`}
        """
        return relationship.one_to_many(cls, 'operation_template', dict_key='name')

    # endregion

    # region many_to_one relationships

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

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

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

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

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

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

    @declared_attr
    def type(cls):
        """
        Interface type.

        :type: :class:`Type`
        """
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # 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

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

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

    @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):
    """
    Template for creating :class:`Operation` instances, which are entry points to Python functions
    called as part of a workflow execution.
    """

    __tablename__ = 'operation_template'

    __private_fields__ = ('service_template_fk',
                          'interface_template_fk',
                          'plugin_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    @declared_attr
    def plugin_specification(cls):
        """
        Associated plugin specification.

        :type: :class:`PluginSpecification`
        """
        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):
        """
        Instantiated operations.

        :type: [:class:`Operation`]
        """
        return relationship.one_to_many(cls, 'operation')

    @declared_attr
    def inputs(cls):
        """
        Declarations for parameters provided to the :attr:`implementation`.

        :type: {:obj:`basestring`: :class:`Input`}
        """
        return relationship.one_to_many(cls, 'input', dict_key='name')

    @declared_attr
    def configurations(cls):
        """
        Configuration parameters for the operation instance Python :attr:`function`.

        :type: {:obj:`basestring`: :class:`Configuration`}
        """
        return relationship.one_to_many(cls, 'configuration', dict_key='name')

    # endregion

    # region many_to_one relationships

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

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

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

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

    # endregion

    # region many_to_many relationships

    # endregion

    # 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

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

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

    relationship_edge = Column(Boolean, doc="""
    When ``True`` specifies that the operation is on the relationship's target edge; ``False`` is
    the source edge (only used by operations on relationships)

    :type: :obj:`bool`
    """)

    implementation = Column(Text, doc="""
    Implementation (usually the name of an artifact).

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

    dependencies = Column(modeling_types.StrictList(item_cls=basestring), doc="""
    Dependencies (usually names of artifacts).

    :type: [:obj:`basestring`]
    """)

    function = Column(Text, doc="""
    Full path to Python function.

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

    executor = Column(Text, doc="""
    Name of executor.

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

    max_attempts = Column(Integer, doc="""
    Maximum number of attempts allowed in case of task failure.

    :type: :obj:`int`
    """)

    retry_interval = Column(Integer, doc="""
    Interval between task retry attemps (in seconds).

    :type: :obj:`float`
    """)

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

    def instantiate(self, container):
        from . import models

        plugin = self.plugin_specification.plugin \
            if (self.plugin_specification is not None) and self.plugin_specification.enabled \
            else None

        operation = models.Operation(name=self.name,
                                     description=deepcopy_with_locators(self.description),
                                     relationship_edge=self.relationship_edge,
                                     implementation=self.implementation,
                                     dependencies=self.dependencies,
                                     executor=self.executor,
                                     plugin=plugin,
                                     function=self.function,
                                     max_attempts=self.max_attempts,
                                     retry_interval=self.retry_interval,
                                     operation_template=self)

        utils.instantiate_dict(container, operation.inputs, self.inputs)
        utils.instantiate_dict(container, operation.configurations, self.configurations)

        return operation

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

    def coerce_values(self, report_issues):
        utils.coerce_dict_values(self.inputs, report_issues)
        utils.coerce_dict_values(self.configurations, 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.implementation is not None:
                console.puts('Implementation: {0}'.format(
                    context.style.literal(self.implementation)))
            if self.dependencies:
                console.puts('Dependencies: {0}'.format(
                    ', '.join((str(context.style.literal(v)) for v in self.dependencies))))
            utils.dump_dict_values(self.inputs, 'Inputs')
            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)))
            if self.plugin_specification is not None:
                console.puts('Plugin specification: {0}'.format(
                    context.style.literal(self.plugin_specification.name)))
            utils.dump_dict_values(self.configurations, 'Configuration')
            if self.function is not None:
                console.puts('Function: {0}'.format(context.style.literal(self.function)))


class ArtifactTemplateBase(TemplateModelMixin):
    """
    Template for creating an :class:`Artifact` instance, which is a typed file, either provided in a
    CSAR or downloaded from a repository.
    """

    __tablename__ = 'artifact_template'

    __private_fields__ = ('type_fk',
                          'node_template_fk')

    # region association proxies

    # endregion

    # region one_to_one relationships

    # endregion

    # region one_to_many relationships

    @declared_attr
    def artifacts(cls):
        """
        Instantiated artifacts.

        :type: [:class:`Artifact`]
        """
        return relationship.one_to_many(cls, 'artifact')

    @declared_attr
    def properties(cls):
        """
        Declarations for associated immutable parameters.

        :type: {:obj:`basestring`: :class:`Property`}
        """
        return relationship.one_to_many(cls, 'property', dict_key='name')

    # endregion

    # region many_to_one relationships

    @declared_attr
    def node_template(cls):
        """
        Containing node template.

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

    @declared_attr
    def type(cls):
        """
        Artifact type.

        :type: :class:`Type`
        """
        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)

    # endregion

    # 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

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

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

    source_path = Column(Text, doc="""
    Source path (in CSAR or repository).

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

    target_path = Column(Text, doc="""
    Path at which to install at destination.

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

    repository_url = Column(Text, doc="""
    Repository URL.

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

    repository_credential = Column(modeling_types.StrictDict(basestring, basestring), doc="""
    Credentials for accessing the repository.

    :type: {:obj:`basestring`, :obj:`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):
    """
    Requirement for a :class:`Plugin`.

    The actual plugin to be selected depends on those currently installed in ARIA.
    """

    __tablename__ = 'plugin_specification'

    __private_fields__ = ('service_template_fk',
                          'plugin_fk')

    version = Column(Text, doc="""
    Minimum plugin version.

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

    enabled = Column(Boolean, nullable=False, default=True, doc="""
    Whether the plugin is enabled.

    :type: :obj:`bool`
    """)

    # region many_to_one relationships

    @declared_attr
    def service_template(cls):
        """
        Containing service template.

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

    @declared_attr
    def plugin(cls): # pylint: disable=method-hidden
        """
        Matched plugin.

        :type: :class:`Plugin`
        """
        return relationship.many_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)

    # endregion

    # 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

    @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
