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

from aria.utils.collections import (FrozenDict, FrozenList)
from aria.utils.caching import cachedmethod
from aria.parser import implements_specification
from aria.parser.presentation import (has_fields, primitive_field, primitive_list_field,
                                      object_field, object_list_field, object_dict_field,
                                      object_sequenced_list_field, field_validator,
                                      type_validator, list_type_validator)

from .assignments import (PropertyAssignment, AttributeAssignment, RequirementAssignment,
                          CapabilityAssignment, InterfaceAssignment, ArtifactAssignment)
from .definitions import ParameterDefinition
from .filters import NodeFilter
from .misc import (Description, MetaData, Repository, Import, SubstitutionMappings)
from .modeling.parameters import (get_assigned_and_defined_parameter_values, get_parameter_values)
from .modeling.interfaces import get_template_interfaces
from .modeling.requirements import get_template_requirements
from .modeling.capabilities import get_template_capabilities
from .modeling.artifacts import get_inherited_artifact_definitions
from .modeling.policies import get_policy_targets
from .modeling.copy import get_default_raw_from_copy
from .modeling.node_templates import validate_type_in_regards_to_substitution_mapping
from .presentation.extensible import ExtensiblePresentation
from .presentation.field_validators import copy_validator, policy_targets_validator
from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType,
                    NodeType, GroupType, PolicyType)


@has_fields
@implements_specification('3.7.3', 'tosca-simple-1.0')
class NodeTemplate(ExtensiblePresentation):
    """
    A Node Template specifies the occurrence of a manageable software component as part of an
    application's topology model which is defined in a TOSCA Service Template. A Node template is an
    instance of a specified Node Type and can provide customized properties, constraints or
    operations which override the defaults provided by its Node Type and its implementations.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ENTITY_NODE_TEMPLATE>`__
    """

    @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
    @primitive_field(str, required=True)
    def type(self):
        """
        The required name of the Node Type the Node Template is based upon.

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

    @object_field(Description)
    def description(self):
        """
        An optional description for the Node Template.

        :type: :class:`Description`
        """

    @primitive_list_field(str)
    def directives(self):
        """
        An optional list of directive values to provide processing instructions to orchestrators and
        tooling.

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

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        An optional list of property value assignments for the Node Template.

        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
        """

    @object_dict_field(AttributeAssignment)
    def attributes(self):
        """
        An optional list of attribute value assignments for the Node Template.

        :type: {:obj:`basestring`: :class:`AttributeAssignment`}
        """

    @object_sequenced_list_field(RequirementAssignment)
    def requirements(self):
        """
        An optional sequenced list of requirement assignments for the Node Template.

        :type: list of (str, :class:`RequirementAssignment`)
        """

    @object_dict_field(CapabilityAssignment)
    def capabilities(self):
        """
        An optional list of capability assignments for the Node Template.

        :type: {:obj:`basestring`: :class:`CapabilityAssignment`}
        """

    @object_dict_field(InterfaceAssignment)
    def interfaces(self):
        """
        An optional list of named interface definitions for the Node Template.

        :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
        """

    @object_dict_field(ArtifactAssignment)
    def artifacts(self):
        """
        An optional list of named artifact definitions for the Node Template.

        :type: {:obj:`basestring`: :class:`ArtifactAssignment`}
        """

    @object_field(NodeFilter)
    def node_filter(self):
        """
        The optional filter definition that TOSCA orchestrators would use to select the correct
        target node. This keyname is only valid if the directive has the value of "selectable" set.

        :type: :class:`NodeFilter`
        """

    @field_validator(copy_validator('node template', 'node_templates'))
    @primitive_field(str)
    def copy(self):
        """
        The optional (symbolic) name of another node template to copy into (all keynames and values)
        and use as a basis for this node template.

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

    @cachedmethod
    def _get_default_raw(self):
        return get_default_raw_from_copy(self, 'node_templates')

    @cachedmethod
    def _get_type(self, context):
        return get_type_by_name(context, self.type, 'node_types')

    @cachedmethod
    def _get_property_values(self, context):
        return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))

    @cachedmethod
    def _get_attribute_default_values(self, context):
        return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'attribute'))

    @cachedmethod
    def _get_requirements(self, context):
        return FrozenList(get_template_requirements(context, self))

    @cachedmethod
    def _get_capabilities(self, context):
        return FrozenDict(get_template_capabilities(context, self))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(get_template_interfaces(context, self, 'node template'))

    @cachedmethod
    def _get_artifacts(self, context):
        return FrozenDict(get_inherited_artifact_definitions(context, self))

    def _validate_type_in_regards_to_substitution_mapping(self, context):
        validate_type_in_regards_to_substitution_mapping(context, self)

    def _validate(self, context):
        super(NodeTemplate, self)._validate(context)
        self._get_property_values(context)
        self._get_requirements(context)
        self._get_capabilities(context)
        self._get_interfaces(context)
        self._get_artifacts(context)
        self._validate_type_in_regards_to_substitution_mapping(context)

    def _dump(self, context):
        self._dump_content(context, (
            'description',
            'type',
            'directives',
            'properties',
            'attributes',
            'requirements',
            'capabilities',
            'interfaces',
            'artifacts',
            'node_filter',
            'copy'))


@has_fields
@implements_specification('3.7.4', 'tosca-simple-1.0')
class RelationshipTemplate(ExtensiblePresentation):
    """
    A Relationship Template specifies the occurrence of a manageable relationship between node
    templates as part of an application's topology model that is defined in a TOSCA Service
    Template. A Relationship template is an instance of a specified Relationship Type and can
    provide customized properties, constraints or operations which override the defaults provided by
    its Relationship Type and its implementations.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ENTITY_RELATIONSHIP_TEMPLATE>`__
    """

    @field_validator(type_validator('relationship type', convert_name_to_full_type_name,
                                    'relationship_types'))
    @primitive_field(str, required=True)
    def type(self):
        """
        The required name of the Relationship Type the Relationship Template is based upon.

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

    @object_field(Description)
    def description(self):
        """
        An optional description for the Relationship Template.

        :type: :class:`Description`
        """

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        An optional list of property assignments for the Relationship Template.

        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
        """

    @object_dict_field(AttributeAssignment)
    def attributes(self):
        """
        An optional list of attribute assignments for the Relationship Template.

        :type: {:obj:`basestring`: :class:`AttributeAssignment`}
        """

    @object_dict_field(InterfaceAssignment)
    def interfaces(self):
        """
        An optional list of named interface definitions for the Node Template.

        ARIA NOTE: Spec is wrong here, should be Relationship Template.

        :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
        """

    @field_validator(copy_validator('relationship template', 'relationship_templates'))
    @primitive_field(str)
    def copy(self):
        """
        The optional (symbolic) name of another relationship template to copy into (all keynames and
        values) and use as a basis for this relationship template.

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

    @cachedmethod
    def _get_default_raw(self):
        return get_default_raw_from_copy(self, 'relationship_templates')

    @cachedmethod
    def _get_type(self, context):
        return get_type_by_name(context, self.type, 'relationship_types')

    @cachedmethod
    def _get_property_values(self, context):
        return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(get_template_interfaces(context, self, 'relationship template'))

    def _validate(self, context):
        super(RelationshipTemplate, self)._validate(context)
        self._get_property_values(context)
        self._get_interfaces(context)

    def _dump(self, context):
        self._dump_content(context, (
            'description',
            'type',
            'properties',
            'attributes',
            'interfaces',
            'copy'))


@has_fields
@implements_specification('3.7.5', 'tosca-simple-1.0')
class GroupTemplate(ExtensiblePresentation):
    """
    A group definition defines a logical grouping of node templates, typically for management
    purposes, but is separate from the application's topology template.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_GROUP_DEF>`__
    """

    @field_validator(type_validator('group type', convert_name_to_full_type_name,
                                    'group_types'))
    @primitive_field(str, required=True)
    def type(self):
        """
        The required name of the group type the group definition is based upon.

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

    @object_field(Description)
    def description(self):
        """
        The optional description for the group definition.

        :type: :class:`Description`
        """

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        An optional list of property value assignments for the group definition.

        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
        """

    @field_validator(list_type_validator('node template', 'topology_template', 'node_templates'))
    @primitive_list_field(str)
    def members(self):
        """
        The optional list of one or more node template names that are members of this group
        definition.

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

    @object_dict_field(InterfaceAssignment)
    def interfaces(self):
        """
        An optional list of named interface definitions for the group definition.

        :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
        """

    @cachedmethod
    def _get_type(self, context):
        return get_type_by_name(context, self.type, 'group_types')

    @cachedmethod
    def _get_property_values(self, context):
        return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))

    @cachedmethod
    def _get_interfaces(self, context):
        return FrozenDict(get_template_interfaces(context, self, 'group definition'))

    def _validate(self, context):
        super(GroupTemplate, self)._validate(context)
        self._get_property_values(context)
        self._get_interfaces(context)


@has_fields
@implements_specification('3.7.6', 'tosca-simple-1.0')
class PolicyTemplate(ExtensiblePresentation):
    """
    A policy definition defines a policy that can be associated with a TOSCA topology or top-level
    entity definition (e.g., group definition, node template, etc.).

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_POLICY_DEF>`__
    """

    @field_validator(type_validator('policy type', convert_name_to_full_type_name, 'policy_types'))
    @primitive_field(str, required=True)
    def type(self):
        """
        The required name of the policy type the policy definition is based upon.

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

    @object_field(Description)
    def description(self):
        """
        The optional description for the policy definition.

        :type: :class:`Description`
        """

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        An optional list of property value assignments for the policy definition.

        :type: {:obj:`basestring`: :class:`PropertyAssignment`
        """

    @field_validator(policy_targets_validator)
    @primitive_list_field(str)
    def targets(self):
        """
        An optional list of valid Node Templates or Groups the Policy can be applied to.

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

    @cachedmethod
    def _get_type(self, context):
        return get_type_by_name(context, self.type, 'policy_types')

    @cachedmethod
    def _get_property_values(self, context):
        return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))

    @cachedmethod
    def _get_targets(self, context):
        node_templates, groups = get_policy_targets(context, self)
        return FrozenList(node_templates), FrozenList(groups)

    def _validate(self, context):
        super(PolicyTemplate, self)._validate(context)
        self._get_property_values(context)


@has_fields
@implements_specification('3.8', 'tosca-simple-1.0')
class TopologyTemplate(ExtensiblePresentation):
    """
    This section defines the topology template of a cloud application. The main ingredients of the
    topology template are node templates representing components of the application and relationship
    templates representing links between the components. These elements are defined in the nested
    ``node_templates`` section and the nested relationship_templates sections, respectively.
    Furthermore, a topology template allows for defining input parameters, output parameters as well
    as grouping of node templates.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ENTITY_TOPOLOGY_TEMPLATE>`__
    """

    @object_field(Description)
    def description(self):
        """
        The optional description for the Topology Template.

        :type: :class:`Description`
        """

    @object_dict_field(ParameterDefinition)
    def inputs(self):
        """
        An optional list of input parameters (i.e., as parameter definitions) for the Topology
        Template.

        :type: {:obj:`basestring`: :class:`ParameterDefinition`}
        """

    @object_dict_field(NodeTemplate)
    def node_templates(self):
        """
        An optional list of node template definitions for the Topology Template.

        :type: {:obj:`basestring`: :class:`NodeTemplate`}
        """

    @object_dict_field(RelationshipTemplate)
    def relationship_templates(self):
        """
        An optional list of relationship templates for the Topology Template.

        :type: {:obj:`basestring`: :class:`RelationshipTemplate`}
        """

    @object_dict_field(GroupTemplate)
    def groups(self):
        """
        An optional list of Group definitions whose members are node templates defined within this
        same Topology Template.

        :class:`GroupTemplate`
        """

    @object_dict_field(PolicyTemplate)
    def policies(self):
        """
        An optional list of Policy definitions for the Topology Template.

        :type: {:obj:`basestring`: :class:`PolicyTemplate`}
        """

    @object_dict_field(ParameterDefinition)
    def outputs(self):
        """
        An optional list of output parameters (i.e., as parameter definitions) for the Topology
        Template.

        :type: {:obj:`basestring`: :class:`ParameterDefinition`}
        """

    @object_field(SubstitutionMappings)
    def substitution_mappings(self):
        """
        An optional declaration that exports the topology template as an implementation of a Node
        type.

        This also includes the mappings between the external Node Types named capabilities and
        requirements to existing implementations of those capabilities and requirements on Node
        templates declared within the topology template.
        """

    @cachedmethod
    def _get_input_values(self, context):
        return FrozenDict(get_parameter_values(context, self, 'inputs'))

    @cachedmethod
    def _get_output_values(self, context):
        return FrozenDict(get_parameter_values(context, self, 'outputs'))

    def _validate(self, context):
        super(TopologyTemplate, self)._validate(context)
        self._get_input_values(context)
        self._get_output_values(context)

    def _dump(self, context):
        self._dump_content(context, (
            'description',
            'inputs',
            'node_templates',
            'relationship_templates',
            'groups',
            'policies',
            'outputs',
            'substitution_mappings'))


@has_fields
@implements_specification('3.9', 'tosca-simple-1.0')
class ServiceTemplate(ExtensiblePresentation):
    """
    Servicate template.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_SERVICE_TEMPLATE>`__.
    """

    @primitive_field(str)
    @implements_specification('3.9.3.1', 'tosca-simple-1.0')
    def tosca_definitions_version(self):
        """
        Defines the version of the TOSCA Simple Profile specification the template (grammar)
        complies with.

        See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
        /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
        #_Toc379455047>`__

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

    @object_field(MetaData)
    def metadata(self):
        """
        Defines a section used to declare additional metadata information. Domain-specific TOSCA
        profile specifications may define keynames that are required for their implementations.

        See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
        /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
        #_Toc379455048>`__

        :type: :class:`MetaData`
        """

    @object_field(Description)
    @implements_specification('3.9.3.6', 'tosca-simple-1.0')
    def description(self):
        """
        Declares a description for this Service Template and its contents.

        :type: :class:`Description`
        """

    @primitive_field()
    @implements_specification('3.9.3.7', 'tosca-simple-1.0')
    def dsl_definitions(self):
        """
        Declares optional DSL-specific definitions and conventions. For example, in YAML, this
        allows defining reusable YAML macros (i.e., YAML alias anchors) for use throughout the TOSCA
        Service Template.

        See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
        /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
        #_Toc397688790>`__
        """

    @object_dict_field(Repository)
    @implements_specification('3.9.3.8', 'tosca-simple-1.0')
    def repositories(self):
        """
        Declares the list of external repositories which contain artifacts that are referenced in
        the service template along with their addresses and necessary credential information used to
        connect to them in order to retrieve the artifacts.

        :type: {:obj:`basestring`: :class:`Repository`}
        """

    @object_list_field(Import)
    @implements_specification('3.9.3.9', 'tosca-simple-1.0')
    def imports(self):
        """
        Declares import statements external TOSCA Definitions documents. For example, these may be
        file location or URIs relative to the service template file within the same TOSCA CSAR file.

        :type: list of :class:`Import`
        """

    @object_dict_field(ArtifactType)
    @implements_specification('3.9.3.10', 'tosca-simple-1.0')
    def artifact_types(self):
        """
        This section contains an optional list of artifact type definitions for use in the service
        template.

        :type: {:obj:`basestring`: :class:`ArtifactType`}
        """

    @object_dict_field(DataType)
    @implements_specification('3.9.3.11', 'tosca-simple-1.0')
    def data_types(self):
        """
        Declares a list of optional TOSCA Data Type definitions.

        :type: {:obj:`basestring`: :class:`DataType`}
        """

    @object_dict_field(CapabilityType)
    @implements_specification('3.9.3.12', 'tosca-simple-1.0')
    def capability_types(self):
        """
        This section contains an optional list of capability type definitions for use in the service
        template.

        :type: {:obj:`basestring`: :class:`CapabilityType`}
        """

    @object_dict_field(InterfaceType)
    @implements_specification('3.9.3.13', 'tosca-simple-1.0')
    def interface_types(self):
        """
        This section contains an optional list of interface type definitions for use in the service
        template.

        :type: {:obj:`basestring`: :class:`InterfaceType`}
        """

    @object_dict_field(RelationshipType)
    @implements_specification('3.9.3.14', 'tosca-simple-1.0')
    def relationship_types(self):
        """
        This section contains a set of relationship type definitions for use in the service
        template.

        :type: {:obj:`basestring`: :class:`RelationshipType`}
        """

    @object_dict_field(NodeType)
    @implements_specification('3.9.3.15', 'tosca-simple-1.0')
    def node_types(self):
        """
        This section contains a set of node type definitions for use in the service template.

        :type: {:obj:`basestring`: :class:`NodeType`}
        """

    @object_dict_field(GroupType)
    @implements_specification('3.9.3.16', 'tosca-simple-1.0')
    def group_types(self):
        """
        This section contains a list of group type definitions for use in the service template.

        :type: {:obj:`basestring`: :class:`GroupType`}
        """

    @object_dict_field(PolicyType)
    @implements_specification('3.9.3.17', 'tosca-simple-1.0')
    def policy_types(self):
        """
        This section contains a list of policy type definitions for use in the service template.

        :type: {:obj:`basestring`: :class:`PolicyType`}
        """

    @object_field(TopologyTemplate)
    def topology_template(self):
        """
        Defines the topology template of an application or service, consisting of node templates
        that represent the application's or service's components, as well as relationship templates
        representing relations between the components.

        :type: :class:`TopologyTemplate`
        """

    def _dump(self, context):
        self._dump_content(context, (
            'description',
            'tosca_definitions_version',
            'metadata',
            'repositories',
            'imports',
            'artifact_types',
            'data_types',
            'capability_types',
            'interface_types',
            'relationship_types',
            'node_types',
            'group_types',
            'policy_types',
            'topology_template'))
