# 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
from aria.utils.caching import cachedmethod
from aria.parser import implements_specification
from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
                                      short_form_field, primitive_field, object_field,
                                      object_dict_field, object_dict_unknown_fields,
                                      field_validator, type_validator)

from .filters import NodeFilter
from .misc import Description, OperationImplementation
from .modeling.parameters import get_assigned_and_defined_parameter_values
from .presentation.extensible import ExtensiblePresentation
from .presentation.field_validators import (node_template_or_type_validator,
                                            relationship_template_or_type_validator,
                                            capability_definition_or_type_validator,
                                            node_filter_validator)
from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)



@implements_specification('3.5.9', 'tosca-simple-1.0')
class PropertyAssignment(AsIsPresentation):
    """
    This section defines the grammar for assigning values to named properties within TOSCA Node and
    Relationship templates that are defined in their corresponding named types.

    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_PROPERTY_VALUE_ASSIGNMENT>`__
    """


@short_form_field('implementation')
@has_fields
@implements_specification('3.5.13-2', 'tosca-simple-1.0')
class OperationAssignment(ExtensiblePresentation):
    """
    An operation definition defines a named function or procedure that can be bound to an
    implementation artifact (e.g., a script).

    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_OPERATION_DEF>`__
    """

    @object_field(Description)
    def description(self):
        """
        The optional description string for the associated named operation.

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

    @object_field(OperationImplementation)
    def implementation(self):
        """
        The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
        file).

        :type: :class:`OperationImplementation`
        """

    @object_dict_field(PropertyAssignment)
    def inputs(self):
        """
        The optional list of input property assignments (i.e., parameters assignments) for operation
        definitions that are within TOSCA Node or Relationship Template definitions. This includes
        when operation definitions are included as part of a Requirement assignment in a Node
        Template.

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

    @cachedmethod
    def _get_extensions(self, context):
        def update_inherited_extensions(extensions, interface_type):
            parent = interface_type._get_parent(context)
            if parent is not None:
                update_inherited_extensions(extensions, parent)
            operation_definition = interface_type.operations.get(self._name)
            if operation_definition is not None:
                if operation_definition._extensions:
                    extensions.update(operation_definition._extensions)

        extensions = {}
        update_inherited_extensions(extensions, self._container._get_type(context))
        if self._container._extensions:
            extensions.update(self._container._extensions)
        if self._extensions:
            extensions.update(self._extensions)
        return extensions


@allow_unknown_fields
@has_fields
@implements_specification('3.5.14-2', 'tosca-simple-1.0')
class InterfaceAssignment(ExtensiblePresentation):
    """
    An interface definition defines a named interface that can be associated with a Node or
    Relationship Type.

    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_INTERFACE_DEF>`__
    """

    @object_dict_field(PropertyAssignment)
    def inputs(self):
        """
        The optional list of input property assignments (i.e., parameters assignments) for interface
        definitions that are within TOSCA Node or Relationship Template definitions. This includes
        when interface definitions are referenced as part of a Requirement assignment in a Node
        Template.

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

    @object_dict_unknown_fields(OperationAssignment)
    def operations(self):
        """
        :type: {:obj:`basestring`: :class:`OperationAssignment`}
        """

    @cachedmethod
    def _get_type(self, context):
        the_type = self._container._get_type(context)

        if isinstance(the_type, tuple):
            # In RelationshipAssignment
            the_type = the_type[0] # This could be a RelationshipTemplate

            if isinstance(self._container._container, RequirementAssignment):
                # In RequirementAssignment
                relationship_definition = \
                    self._container._container._get_relationship_definition(context)
                interface_definitions = relationship_definition.interfaces \
                    if relationship_definition is not None else None
                if (interface_definitions is not None) and (self._name in interface_definitions):
                    return interface_definitions[self._name]._get_type(context)

        interface_definitions = the_type._get_interfaces(context) \
            if the_type is not None else None
        interface_definition = interface_definitions.get(self._name) \
            if interface_definitions is not None else None
        return interface_definition._get_type(context) \
            if interface_definition is not None else None

    def _validate(self, context):
        super(InterfaceAssignment, self)._validate(context)
        if self.operations:
            for operation in self.operations.itervalues():                                          # pylint: disable=no-member
                operation._validate(context)


@short_form_field('type')
@has_fields
class RelationshipAssignment(ExtensiblePresentation):
    """
    Relationship assignment.
    """

    @field_validator(relationship_template_or_type_validator)
    @primitive_field(str)
    def type(self):
        """
        The optional reserved keyname used to provide the name of the Relationship Type for the
        requirement assignment's relationship keyname.

        ARIA NOTE: this can also be a relationship template name.

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

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        ARIA NOTE: This field is not mentioned in the spec, but is implied.

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

    @object_dict_field(InterfaceAssignment)
    def interfaces(self):
        """
        The optional reserved keyname used to reference declared (named) interface definitions of
        the corresponding Relationship Type in order to provide Property assignments for these
        interfaces or operations of these interfaces.

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

    @cachedmethod
    def _get_type(self, context):
        type_name = self.type
        if type_name is not None:
            the_type = context.presentation.get_from_dict('service_template', 'topology_template',
                                                          'relationship_templates', type_name)
            if the_type is not None:
                return the_type, 'relationship_template'
            the_type = get_type_by_name(context, type_name, 'relationship_types')
            if the_type is not None:
                return the_type, 'relationship_type'
        return None, None


@short_form_field('node')
@has_fields
@implements_specification('3.7.2', 'tosca-simple-1.0')
class RequirementAssignment(ExtensiblePresentation):
    """
    A Requirement assignment allows template authors to provide either concrete names of TOSCA
    templates or provide abstract selection criteria for providers to use to find matching TOSCA
    templates that are used to fulfill a named requirement's declared TOSCA Node Type.

    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_REQUIREMENT_ASSIGNMENT>`__
    """

    # The example in 3.7.2.2.2 shows unknown fields in addition to these, but is this a mistake?

    @field_validator(capability_definition_or_type_validator)
    @primitive_field(str)
    def capability(self):
        """
        The optional reserved keyname used to provide the name of either a:

        * Capability definition within a target node template that can fulfill the requirement.
        * Capability Type that the provider will use to select a type-compatible target node
          template to fulfill the requirement at runtime.

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

    @field_validator(node_template_or_type_validator)
    @primitive_field(str)
    def node(self):
        """
        The optional reserved keyname used to identify the target node of a relationship.
        Specifically, it is used to provide either a:

        * Node Template name that can fulfill the target node requirement.
        * Node Type name that the provider will use to select a type-compatible node template to
          fulfill the requirement at runtime.

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

    @object_field(RelationshipAssignment)
    def relationship(self):
        """
        The optional reserved keyname used to provide the name of either a:

        * Relationship Template to use to relate the source node to the (capability in the) target
          node when fulfilling the requirement.
        * Relationship Type that the provider will use to select a type-compatible relationship
          template to relate the source node to the target node at runtime.

        :type: :class:`RelationshipAssignment`
        """

    @field_validator(node_filter_validator)
    @object_field(NodeFilter)
    def node_filter(self):
        """
        The optional filter definition that TOSCA orchestrators or providers would use to select a
        type-compatible target node that can fulfill the associated abstract requirement at runtime.

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

    @cachedmethod
    def _get_node(self, context):
        node = self.node

        if node is not None:
            node_template = context.presentation.get_from_dict('service_template',
                                                               'topology_template',
                                                               'node_templates', node)
            if node_template is not None:
                return node_template, 'node_template'
            node_type = get_type_by_name(context, node, 'node_types')
            if node_type is not None:
                return node_type, 'node_type'

        return None, None

    @cachedmethod
    def _get_definition(self, context):
        node_type = self._container._get_type(context)
        if (node_type is not None) and (node_type.requirements is not None):
            for name, requirement in node_type.requirements:
                if name == self._name:
                    return requirement
        return None

    @cachedmethod
    def _get_relationship_definition(self, context):
        requirement_definition = self._get_definition(context)
        return requirement_definition.relationship if requirement_definition is not None else None

    @cachedmethod
    def _get_capability(self, context):
        capability = self.capability

        if capability is not None:
            node, node_variant = self._get_node(context)
            if node_variant == 'node_template':
                capabilities = node._get_capabilities(context)
                if capability in capabilities:
                    return capabilities[capability], 'capability_assignment'
            capability_type = get_type_by_name(context, capability, 'capability_types')
            if capability_type is not None:
                return capability_type, 'capability_type'

        return None, None


@implements_specification('3.5.11', 'tosca-simple-1.0')
class AttributeAssignment(AsIsPresentation):
    """
    This section defines the grammar for assigning values to named attributes within TOSCA Node and
    Relationship templates which are defined in their corresponding named types.

    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_ATTRIBUTE_VALUE_ASSIGNMENT>`__
    """


@has_fields
@implements_specification('3.7.1', 'tosca-simple-1.0')
class CapabilityAssignment(ExtensiblePresentation):
    """
    A capability assignment allows node template authors to assign values to properties and
    attributes for a named capability definition that is part of a Node Template's type definition.

    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_CAPABILITY_ASSIGNMENT>`__
    """

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        An optional list of property definitions for the Capability definition.

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

    @object_dict_field(AttributeAssignment)
    def attributes(self):
        """
        An optional list of attribute definitions for the Capability definition.

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

    @cachedmethod
    def _get_definition(self, context):
        node_type = self._container._get_type(context)
        capability_definitions = node_type._get_capabilities(context) \
            if node_type is not None else None
        return capability_definitions.get(self._name) \
            if capability_definitions is not None else None

    @cachedmethod
    def _get_type(self, context):
        capability_definition = self._get_definition(context)
        return capability_definition._get_type(context) \
            if capability_definition is not None else None


@has_fields
@implements_specification('3.5.6', 'tosca-simple-1.0')
class ArtifactAssignmentForType(ExtensiblePresentation):
    """
    An artifact definition defines a named, typed file that can be associated with Node Type or Node
    Template and used by orchestration engine to facilitate deployment and implementation of
    interface operations.

    ARIA NOTE: section 3.5.6.2.1 in the spec refers to a short notation for "file", but that
    notation would be impossible because the "type" field is required.

    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_ARTIFACT_DEF>`__
    """

    @field_validator(type_validator('artifact type', convert_name_to_full_type_name,
                                    'artifact_types'))
    @primitive_field(str, required=True)
    def type(self):
        """
        The required artifact type for the artifact definition.

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

    @primitive_field(str, required=True)
    def file(self):
        """
        The required URI string (relative or absolute) which can be used to locate the artifact's
        file.

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

    @field_validator(type_validator('repository', 'repositories'))
    @primitive_field(str)
    def repository(self):
        """
        The optional name of the repository definition which contains the location of the external
        repository that contains the artifact. The artifact is expected to be referenceable by its
        file URI within the repository.

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

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

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

    @primitive_field(str)
    def deploy_path(self):
        """
        The file path the associated file would be deployed into within the target node's container.

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

    @object_dict_field(PropertyAssignment)
    def properties(self):
        """
        ARIA NOTE: This field is not mentioned in the spec, but is implied.

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

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

    @cachedmethod
    def _get_repository(self, context):
        return context.presentation.get_from_dict('service_template', 'repositories',
                                                  self.repository)

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

    @cachedmethod
    def _validate(self, context):
        super(ArtifactAssignmentForType, self)._validate(context)


class ArtifactAssignment(ArtifactAssignmentForType):
    @cachedmethod
    def _validate(self, context):
        super(ArtifactAssignment, self)._validate(context)
        self._get_property_values(context)
