#!/usr/bin/python
#
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script reads the global interface data collected by
# compute_interfaces_info_overall.py, and writes out the code which adds
# bindings for origin-trial-enabled features at runtime.

import optparse
import os
import posixpath
import sys
from collections import defaultdict, namedtuple

from code_generator import (initialize_jinja_env, normalize_and_sort_includes,
                            render_template)
from idl_reader import IdlReader
from utilities import (create_component_info_provider, write_file,
                       idl_filename_to_component)
from v8_utilities import (binding_header_filename, v8_class_name,
                          v8_class_name_or_partial, origin_trial_feature_name)

# Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'

OriginTrialInterfaceInfo = namedtuple(
    'OriginTrialInterfaceInfo',
    ['name', 'v8_class', 'v8_class_or_partial', 'is_global'])


def get_install_functions(interfaces, feature_names):
    """Construct a list of V8 bindings installation functions for each feature
    on each interface.

    interfaces is a list of OriginTrialInterfaceInfo tuples
    feature_names is a list of strings, containing names of features which can
        be installed on those interfaces.
    """
    return [{
        'condition':
        'RuntimeEnabledFeatures::%sEnabled' % feature_name,
        'name':
        feature_name,
        'install_method':
        'Install%s' % feature_name,
        'interface_is_global':
        interface_info.is_global,
        'global_type_check_method':
        interface_global_type_check_method(interface_info),
        'v8_class':
        interface_info.v8_class,
        'v8_class_or_partial':
        interface_info.v8_class_or_partial,
    } for feature_name in feature_names for interface_info in interfaces]


def get_origin_trial_feature_names_from_interface(interface, runtime_features):
    feature_names = set()

    def add_if_not_none(value):
        if value:
            feature_names.add(value)

    if interface.is_partial:
        add_if_not_none(origin_trial_feature_name(interface, runtime_features))
    for operation in interface.operations:
        add_if_not_none(origin_trial_feature_name(operation, runtime_features))
    for attribute in interface.attributes:
        add_if_not_none(origin_trial_feature_name(attribute, runtime_features))
    return feature_names


def read_idl_file(reader, idl_filename):
    definitions = reader.read_idl_file(idl_filename)
    interfaces = definitions.interfaces
    includes = definitions.includes
    # There should only be a single interface defined in an IDL file. Return it.
    assert len(interfaces) == 1, (
        "Expected one interface in file %r, found %d" %
        (idl_filename, len(interfaces)))
    return (list(interfaces.values())[0], includes)


def interface_is_global(interface):
    return 'Global' in interface.extended_attributes


def interface_global_type_check_method(interface_info):
    """Generate the name of the method on ExecutionContext used to check if the
       context matches the type of the interface, which is a global.

       Returns None for non-global interfaces.
    """
    if not interface_info.is_global:
        return None

    return 'Is%s' % interface_info.name


def origin_trial_features_info(info_provider, reader, idl_filenames,
                               target_component):
    """Read a set of IDL files and compile the mapping between interfaces and
    the conditional features defined on them.

    Returns a tuple (features_for_type, types_for_feature, includes):
      - features_for_type is a mapping of interface->feature
      - types_for_feature is the reverse mapping: feature->interface
      - includes is a set of header files which need to be included in the
          generated implementation code.
    """
    features_for_type = defaultdict(set)
    types_for_feature = defaultdict(set)
    include_files = set()
    runtime_features = info_provider.component_info['runtime_enabled_features']

    for idl_filename in idl_filenames:
        interface, includes = read_idl_file(reader, idl_filename)
        feature_names = get_origin_trial_feature_names_from_interface(
            interface, runtime_features)

        # If this interface is a mixin, we don't generate V8 bindings code for
        # it.
        # TODO(crbug.com/1061995): This incorrectly ignores includes in the
        # mixin idl like "SomeInterface includes MixinInterface".
        if interface.is_mixin:
            continue

        # If this interface include another one,
        # it inherits any conditional features from it.
        for include in includes:
            assert include.interface == interface.name, (
                "'includes' interface identifier %r in file %r should be  %r" %
                (include.interface, idl_filename, interface.name))
            mixin, _ = read_idl_file(
                reader,
                info_provider.interfaces_info[include.mixin].get('full_path'))
            feature_names |= get_origin_trial_feature_names_from_interface(
                mixin, runtime_features)

        feature_names = list(feature_names)
        if feature_names:
            is_global = interface_is_global(interface)
            if interface.is_partial:
                # For partial interfaces, we need to generate different
                # |include_files| if the parent interface is in a different
                # component.
                parent_interface_info = \
                    info_provider.interfaces_info[interface.name]
                parent_interface, _ = read_idl_file(
                    reader, parent_interface_info.get('full_path'))
                is_global = is_global or interface_is_global(parent_interface)
                parent_component = idl_filename_to_component(
                    parent_interface_info.get('full_path'))
            if interface.is_partial and target_component != parent_component:
                include_files.add('bindings/%s/v8/%s' % (
                    parent_component, binding_header_filename(interface.name)))
                include_files.add(
                    'bindings/%s/v8/%s' %
                    (target_component,
                     binding_header_filename(interface.name + 'Partial')))
            else:
                include_files.add('bindings/%s/v8/%s' % (
                    target_component, binding_header_filename(interface.name)))
                # If this is a partial interface in the same component as
                # its parent, then treat it as a non-partial interface.
                interface.is_partial = False
            interface_info = OriginTrialInterfaceInfo(
                interface.name, v8_class_name(interface),
                v8_class_name_or_partial(interface), is_global)
            for feature_name in feature_names:
                features_for_type[interface_info].add(feature_name)
                types_for_feature[feature_name].add(interface_info)

    return features_for_type, types_for_feature, include_files


def origin_trial_features_context(generator_name, feature_info):
    context = {'code_generator': generator_name}

    # Unpack the feature info tuple.
    features_for_type, types_for_feature, include_files = feature_info

    # Add includes needed for cpp code and normalize.
    include_files.update([
        'core/context_features/context_feature_settings.h',
        'core/execution_context/execution_context.h',
        'core/frame/frame.h',
        'core/origin_trials/origin_trials.h',
        'platform/bindings/origin_trial_features.h',
        'platform/bindings/script_state.h',
        'platform/bindings/v8_per_context_data.h',
        'platform/runtime_enabled_features.h',
        # TODO(iclelland): Remove the need to explicitly include this; it is
        # here because the ContextFeatureSettings code needs it.
        'bindings/core/v8/v8_window.h',
    ])
    context['includes'] = normalize_and_sort_includes(include_files)

    # For each interface, collect a list of bindings installation functions to
    # call, organized by conditional feature.
    context['installers_by_interface'] = [{
        'name':
        interface_info.name,
        'is_global':
        interface_info.is_global,
        'v8_class':
        interface_info.v8_class,
        'installers':
        get_install_functions([interface_info], feature_names)
    } for interface_info, feature_names in features_for_type.items()]
    context['installers_by_interface'].sort(key=lambda x: x['name'])

    # For each conditional feature, collect a list of bindings installation
    # functions to call, organized by interface.
    context['installers_by_feature'] = [{
        'name':
        feature_name,
        'name_constant':
        'OriginTrialFeature::k%s' % feature_name,
        'installers':
        get_install_functions(interfaces, [feature_name])
    } for feature_name, interfaces in types_for_feature.items()]
    context['installers_by_feature'].sort(key=lambda x: x['name'])

    return context


def parse_options():
    parser = optparse.OptionParser()
    parser.add_option(
        '--cache-directory',
        help='cache directory, defaults to output directory')
    parser.add_option('--output-directory')
    parser.add_option('--info-dir')
    parser.add_option(
        '--target-component',
        type='choice',
        choices=['core', 'modules'],
        help='target component to generate code')
    parser.add_option('--idl-files-list')

    options, _ = parser.parse_args()
    if options.output_directory is None:
        parser.error('Must specify output directory using --output-directory.')
    return options


def generate_origin_trial_features(info_provider, options, idl_filenames):
    reader = IdlReader(info_provider.interfaces_info, options.cache_directory)
    jinja_env = initialize_jinja_env(options.cache_directory)

    # Extract the bidirectional mapping of conditional features <-> interfaces
    # from the global info provider and the supplied list of IDL files.
    feature_info = origin_trial_features_info(
        info_provider, reader, idl_filenames, options.target_component)

    # Convert that mapping into the context required for the Jinja2 templates.
    template_context = origin_trial_features_context(MODULE_PYNAME,
                                                     feature_info)

    file_basename = 'origin_trial_features_for_%s' % options.target_component

    # Generate and write out the header file
    header_text = render_template(
        jinja_env.get_template(file_basename + '.h.tmpl'), template_context)
    header_path = posixpath.join(options.output_directory,
                                 file_basename + '.h')
    write_file(header_text, header_path)

    # Generate and write out the implementation file
    cpp_text = render_template(
        jinja_env.get_template(file_basename + '.cc.tmpl'), template_context)
    cpp_path = posixpath.join(options.output_directory, file_basename + '.cc')
    write_file(cpp_text, cpp_path)


def main():
    options = parse_options()

    info_provider = create_component_info_provider(
        os.path.normpath(options.info_dir), options.target_component)
    idl_filenames = list(map(str.strip, open(options.idl_files_list)))

    generate_origin_trial_features(info_provider, options, idl_filenames)
    return 0


if __name__ == '__main__':
    sys.exit(main())
