# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Resolve interface dependencies, producing a merged IdlDefinitions object.

This library computes interface dependencies (partial interfaces and
implements), reads the dependency files, and merges them to the IdlDefinitions
for the main IDL file, producing an IdlDefinitions object representing the
entire interface.

Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Dependency-resolution
"""

import os.path

# The following extended attributes can be applied to a dependency interface,
# and are then applied to the individual members when merging.
# Note that this moves the extended attribute from the interface to the member,
# which changes the semantics and yields different code than the same extended
# attribute on the main interface.
DEPENDENCY_EXTENDED_ATTRIBUTES = set([
    'Conditional',
    'PerContextEnabled',
    'RuntimeEnabled',
])


class InterfaceDependencyResolver(object):
    def __init__(self, interfaces_info, reader):
        """Initialize dependency resolver.

        Args:
            interfaces_info:
                dict of interfaces information, from compute_dependencies.py
            reader:
                IdlReader, used for reading dependency files
        """
        self.interfaces_info = interfaces_info
        self.reader = reader

    def resolve_dependencies(self, definitions, component):
        """Resolve dependencies, merging them into IDL definitions of main file.

        Dependencies consist of 'partial interface' for the same interface as
        in the main file, and other interfaces that this interface 'implements'.
        These are merged into the main IdlInterface, as the main IdlInterface
        implements all these members.

        Referenced interfaces are added to IdlDefinitions, but not merged into
        the main IdlInterface, as these are only referenced (their members are
        introspected, but not implemented in this interface).

        Inherited extended attributes are also added to the main IdlInterface.

        Modifies definitions in place by adding parsed dependencies.

        Args:
            definitions: IdlDefinitions object, modified in place
            component:
                string, describing where the above definitions are defined,
                'core' or 'modules'. See KNOWN_COMPONENTS in utilities.py

        Returns:
            A dictionary whose key is component and value is IdlDefinitions
            object whose dependency is resolved.

        Raises:
            Exception:
                A given IdlDefinitions object doesn't have any interfaces,
                or a given IdlDefinitions object has incorrect referenced
                interfaces.
        """
        # FIXME: we need to resolve dependency when we implement partial
        # dictionary.
        if not definitions.interfaces:
            raise Exception('No need to resolve any dependencies of '
                            'this definition: %s, because this should '
                            'have a dictionary.' % definitions.idl_name)

        target_interface = next(definitions.interfaces.itervalues())
        interface_name = target_interface.name
        interface_info = self.interfaces_info[interface_name]

        if 'inherited_extended_attributes' in interface_info:
            target_interface.extended_attributes.update(
                interface_info['inherited_extended_attributes'])

        resolved_definitions = merge_interface_dependencies(
            definitions,
            component,
            target_interface,
            interface_info['dependencies_full_paths'],
            self.reader)

        for referenced_interface_name in interface_info['referenced_interfaces']:
            referenced_definitions = self.reader.read_idl_definitions(
                self.interfaces_info[referenced_interface_name]['full_path'])

            if component not in referenced_definitions:
                raise Exception('This definitions: %s is defined in %s '
                                'but reference interface:%s is not defined '
                                'in %s' % (definitions.idl_name,
                                           component,
                                           referenced_interface_name,
                                           component))

            resolved_definitions[component].update(referenced_definitions[component])
        return resolved_definitions


def merge_interface_dependencies(definitions, component, target_interface, dependency_idl_filenames, reader):
    """Merge dependencies ('partial interface' and 'implements') in dependency_idl_filenames into target_interface.

    No return: modifies target_interface in place.
    """
    # Sort so order consistent, so can compare output from run to run.
    for dependency_idl_filename in sorted(dependency_idl_filenames):
        dependency_definitions = reader.read_idl_file(dependency_idl_filename)
        # FIXME(crbug.com/358074): should not merge core definitions with
        # modules definitions.
        dependency_interface = next(dependency_definitions.interfaces.itervalues())
        dependency_interface_basename, _ = os.path.splitext(os.path.basename(dependency_idl_filename))

        transfer_extended_attributes(dependency_interface,
                                     dependency_interface_basename)
        definitions.update(dependency_definitions)  # merges partial interfaces
        if not dependency_interface.is_partial:
            # Implemented interfaces (non-partial dependencies) are also merged
            # into the target interface, so Code Generator can just iterate
            # over one list (and not need to handle 'implements' itself).
            target_interface.merge(dependency_interface)

    # FIXME: Currently, this function just returns one IdlDefinitions
    # instance. However, for partial interface modularization, we need to
    # make this function return multiple definitions, i.e.
    # { 'core': ..., 'modules': ... }.
    return {component: definitions}


def transfer_extended_attributes(dependency_interface, dependency_interface_basename):
    """Transfer extended attributes from dependency interface onto members.

    Merging consists of storing certain interface-level data in extended
    attributes of the *members* (because there is no separate dependency
    interface post-merging).

    The data storing consists of:
    * applying certain extended attributes from the dependency interface
      to its members
    * storing the C++ class of the implementation in an internal
      extended attribute of each member, [PartialInterfaceImplementedAs]

    No return: modifies dependency_interface in place.
    """
    merged_extended_attributes = dict(
        (key, value)
        for key, value in dependency_interface.extended_attributes.iteritems()
        if key in DEPENDENCY_EXTENDED_ATTRIBUTES)

    # A partial interface's members are implemented as static member functions
    # in a separate C++ class. This class name is stored in
    # [PartialInterfaceImplementedAs] which defaults to the basename of
    # dependency IDL file.
    # This class name can be overridden by [ImplementedAs] on the partial
    # interface definition.
    #
    # Note that implemented interfaces do *not* need [ImplementedAs], since
    # they are implemented on the C++ object |impl| itself, just like members of
    # the main interface definition, so the bindings do not need to know in
    # which class implemented interfaces are implemented.
    #
    # Currently [LegacyTreatAsPartialInterface] can be used to have partial
    # interface behavior on implemented interfaces, but this is being removed
    # as legacy cruft:
    # FIXME: Remove [LegacyTreatAsPartialInterface]
    # http://crbug.com/360435
    #
    # Note that [ImplementedAs] is used with different meanings on interfaces
    # and members:
    # for Blink class name and function name (or constant name), respectively.
    # Thus we do not want to copy this from the interface to the member, but
    # instead extract it and handle it separately.
    if (dependency_interface.is_partial or
        'LegacyTreatAsPartialInterface' in dependency_interface.extended_attributes):
        merged_extended_attributes['PartialInterfaceImplementedAs'] = (
            dependency_interface.extended_attributes.get(
                'ImplementedAs', dependency_interface_basename))

    for attribute in dependency_interface.attributes:
        attribute.extended_attributes.update(merged_extended_attributes)
    for constant in dependency_interface.constants:
        constant.extended_attributes.update(merged_extended_attributes)
    for operation in dependency_interface.operations:
        operation.extended_attributes.update(merged_extended_attributes)
