# Copyright 2014 The Cobalt Authors. All Rights Reserved.
#
# Licensed 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.
"""Generate Cobalt bindings (.h and .cpp files).

Based on and borrows heavily from code_generator_v8.py which is used as part
of the bindings generation pipeline in Blink.
"""

import abc
from datetime import date
import os
import sys

bindings_dir = os.path.join(
    os.path.dirname(__file__),
    '../../third_party/blink/Source/bindings/scripts')
sys.path.insert(0, bindings_dir)

# pylint:disable=wrong-import-position
from cobalt.bindings import path_generator
from cobalt.bindings.contexts import ContextBuilder
from cobalt.bindings.name_conversion import get_interface_name
from code_generator import CodeGeneratorBase
from code_generator import jinja2
from idl_definitions import IdlTypedef
from idl_types import IdlSequenceType
from idl_types import IdlType

module_path, module_filename = os.path.split(os.path.realpath(__file__))

# Track the cobalt directory, so we can use it for building relative paths.
cobalt_dir = os.path.normpath(os.path.join(module_path, os.pardir))

SHARED_TEMPLATES_DIR = os.path.abspath(os.path.join(module_path, 'templates'))


def initialize_jinja_env(cache_dir, templates_dir):
  """Initialize the Jinja2 environment."""
  assert os.path.isabs(templates_dir)
  assert os.path.isabs(SHARED_TEMPLATES_DIR)
  jinja_env = jinja2.Environment(
      loader=jinja2.FileSystemLoader([templates_dir, SHARED_TEMPLATES_DIR]),
      extensions=['jinja2.ext.do'],  # do statement
      # Bytecode cache is not concurrency-safe unless pre-cached:
      # if pre-cached this is read-only, but writing creates a race condition.
      bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir),
      keep_trailing_newline=True,  # newline-terminate generated files
      lstrip_blocks=True,  # so can indent control flow tags
      trim_blocks=True)
  return jinja_env


def normalize_slashes(path):
  if os.path.sep == '\\':
    return path.replace('\\', '/')
  else:
    return path


def is_global_interface(interface):
  return (('PrimaryGlobal' in interface.extended_attributes) or
          ('Global' in interface.extended_attributes))


def get_indexed_special_operation(interface, special):
  special_operations = list(
      operation for operation in interface.operations
      if (special in operation.specials and operation.arguments and
          str(operation.arguments[0].idl_type) == 'unsigned long'))
  assert len(special_operations) <= 1, (
      f'Multiple indexed {special}s defined on interface: {interface.name}')
  return special_operations[0] if special_operations else None


def get_indexed_property_getter(interface):
  getter_operation = get_indexed_special_operation(interface, 'getter')
  assert not getter_operation or len(getter_operation.arguments) == 1
  return getter_operation


def get_indexed_property_setter(interface):
  setter_operation = get_indexed_special_operation(interface, 'setter')
  assert not setter_operation or len(setter_operation.arguments) == 2
  return setter_operation


def get_indexed_property_deleter(interface):
  deleter_operation = get_indexed_special_operation(interface, 'deleter')
  assert not deleter_operation or len(deleter_operation.arguments) == 1
  return deleter_operation


def get_named_special_operation(interface, special):
  special_operations = list(
      operation for operation in interface.operations
      if (special in operation.specials and operation.arguments and
          str(operation.arguments[0].idl_type) == 'DOMString'))
  assert len(special_operations) <= 1, (
      f'Multiple named {special}s defined on interface: {interface.name}')
  return special_operations[0] if special_operations else None


def get_named_property_getter(interface):
  getter_operation = get_named_special_operation(interface, 'getter')
  assert not getter_operation or len(getter_operation.arguments) == 1
  return getter_operation


def get_named_property_setter(interface):
  setter_operation = get_named_special_operation(interface, 'setter')
  assert not setter_operation or len(setter_operation.arguments) == 2
  return setter_operation


def get_named_property_deleter(interface):
  deleter_operation = get_named_special_operation(interface, 'deleter')
  assert not deleter_operation or len(deleter_operation.arguments) == 1
  return deleter_operation


def get_interface_type_names_from_idl_types(info_provider, idl_type_list):
  for idl_type in idl_type_list:
    if idl_type:
      idl_type = idl_type.resolve_typedefs(info_provider.typedefs)
      if isinstance(idl_type, IdlTypedef):
        idl_type = idl_type.idl_type
      if idl_type.is_nullable:
        idl_type = idl_type.inner_type

      if idl_type.is_interface_type:
        yield get_interface_name(idl_type)
      if idl_type.is_dictionary:
        yield idl_type.name
      elif idl_type.is_union_type:
        for interface_name in get_interface_type_names_from_idl_types(
            info_provider, idl_type.member_types):
          yield interface_name
      elif idl_type.is_enum:
        yield idl_type.name
      elif isinstance(idl_type, IdlSequenceType):
        for interface_name in get_interface_type_names_from_idl_types(
            info_provider, [idl_type.element_type]):
          yield interface_name


def get_interface_type_names_from_typed_objects(info_provider,
                                                typed_object_list):
  for typed_object in typed_object_list:
    for interface_name in get_interface_type_names_from_idl_types(
        info_provider, [typed_object.idl_type]):
      yield interface_name

    if hasattr(typed_object, 'arguments'):
      for interface_name in get_interface_type_names_from_typed_objects(
          info_provider, typed_object.arguments):
        yield interface_name


def split_unsupported_properties(context_list):
  supported = []
  unsupported = []
  for context in context_list:
    if context['unsupported']:
      unsupported.append(context['idl_name'])
    else:
      supported.append(context)
  return supported, unsupported


class CodeGeneratorCobalt(CodeGeneratorBase):
  """Abstract Base code generator class for Cobalt.

  Concrete classes will provide an implementation for generating bindings for a
  specific JavaScript engine implementation.
  """
  __metaclass__ = abc.ABCMeta

  def __init__(self, templates_dir, info_provider, cache_dir, output_dir):
    super().__init__('CodeGeneratorCobalt', info_provider, cache_dir,
                     output_dir)
    # CodeGeneratorBase inititalizes this with the v8 template path, so
    # reinitialize it with cobalt's template path

    # Whether the path is absolute or relative affects the cache file name. Use
    # the absolute path to ensure that we use the same path as was used when the
    # cache was prepopulated.
    self.jinja_env = initialize_jinja_env(cache_dir,
                                          os.path.abspath(templates_dir))
    self.path_builder = path_generator.PathBuilder(self.generated_file_prefix,
                                                   self.info_provider,
                                                   cobalt_dir, output_dir)

  def generated_file_prefix(self):
    """The prefix to prepend to all generated source files."""
    pass

  def expression_generator(self):
    """An instance that implements the ExpressionGenerator class."""
    pass

  def render_template(self, template_filename, template_context):
    template = self.jinja_env.get_template(template_filename)
    template_context.update(self.common_context(template))
    rendered_text = template.render(template_context)
    return rendered_text

  def generate_code(self, definitions, definition_name):
    if definition_name in definitions.interfaces:
      return self.generate_interface_code(
          definitions, definition_name, definitions.interfaces[definition_name])
    if definition_name in definitions.dictionaries:
      return self.generate_dictionary_code(
          definition_name, definitions.dictionaries[definition_name])
    if definition_name in definitions.enumerations:
      return self.generate_enum_code(definition_name,
                                     definitions.enumerations[definition_name])
    raise ValueError(f'{definition_name} is not in IDL definitions')

  def generate_interface_code(self, definitions, interface_name, interface):
    interface_info = self.info_provider.interfaces_info[interface_name]
    # Select appropriate Jinja template and contents function
    if interface.is_callback:
      header_template_filename = 'callback-interface.h.template'
      cpp_template_filename = 'callback-interface.cc.template'
    elif interface.is_partial:
      raise NotImplementedError('Partial interfaces not implemented')
    else:
      header_template_filename = 'interface.h.template'
      cpp_template_filename = 'interface.cc.template'

    template_context = self.build_interface_context(interface, interface_info,
                                                    definitions)
    header_text = self.render_template(header_template_filename,
                                       template_context)
    cc_text = self.render_template(cpp_template_filename, template_context)
    header_path = self.path_builder.BindingsHeaderFullPath(interface_name)
    cc_path = self.path_builder.BindingsImplementationPath(interface_name)
    return (
        (header_path, header_text),
        (cc_path, cc_text),
    )

  def generate_dictionary_code(self, dictionary_name, dictionary):
    header_template_filename = 'dictionary.h.template'
    conversion_template_filename = 'dictionary-conversion.cc.template'
    implementation_context = self.build_dictionary_context(dictionary, False)
    conversion_context = self.build_dictionary_context(dictionary, True)

    header_text = self.render_template(header_template_filename,
                                       implementation_context)
    conversion_text = self.render_template(conversion_template_filename,
                                           conversion_context)

    header_path = self.path_builder.DictionaryHeaderFullPath(dictionary_name)
    conversion_impl_path = (
        self.path_builder.DictionaryConversionImplementationPath(
            dictionary_name))
    return (
        (header_path, header_text),
        (conversion_impl_path, conversion_text),
    )

  def generate_enum_code(self, enumeration_name, enumeration):
    header_template_filename = 'enumeration.h.template'
    conversion_template_filename = 'enumeration-conversion.cc.template'
    context_builder = ContextBuilder(self.info_provider)
    context = context_builder.enumeration_context(enumeration)

    context['components'] = self.path_builder.NamespaceComponents(
        enumeration_name)
    context['namespace'] = self.path_builder.Namespace(enumeration_name)
    context['fully_qualified_name'] = self.path_builder.FullClassName(
        enumeration_name)
    context['enum_include'] = self.path_builder.EnumHeaderIncludePath(
        enumeration_name)

    header_text = self.render_template(header_template_filename, context)
    conversion_text = self.render_template(conversion_template_filename,
                                           context)

    header_path = self.path_builder.EnumHeaderFullPath(enumeration_name)
    conversion_impl_path = (
        self.path_builder.EnumConversionImplementationFullPath(enumeration_name)
    )
    return (
        (header_path, header_text),
        (conversion_impl_path, conversion_text),
    )

  def generate_conversion_code(self):
    enumerations = list(self.info_provider.enumerations.keys())
    dictionaries = list(self.info_provider.interfaces_info['dictionaries'])
    includes = [
        self.path_builder.DictionaryHeaderIncludePath(dictionary)
        for dictionary in dictionaries
    ]
    includes.extend([
        self.path_builder.EnumHeaderIncludePath(enum) for enum in enumerations
    ])

    context = {
        'dictionaries': self.referenced_class_contexts(dictionaries, False),
        'enumerations': self.referenced_class_contexts(enumerations, False),
        'includes': includes,
    }

    header_template_filename = 'generated-types.h.template'
    header_text = self.render_template(header_template_filename, context)

    return self.path_builder.generated_conversion_header_path, header_text

  def referenced_dictionary_context(self, dictionary_name, dictionary_info):
    namespace = '::'.join(
        self.path_builder.NamespaceComponents(dictionary_name))

    return {
        'fully_qualified_name':
            f'{namespace}::{dictionary_name}',
        'include':
            self.path_builder.DictionaryHeaderIncludePath(dictionary_name),
        'conditional':
            dictionary_info['conditional'],
        'is_callback_interface':
            False,
    }

  def referenced_enum_context(self, enum_name):
    namespace = '::'.join(self.path_builder.NamespaceComponents(enum_name))
    return {
        'fully_qualified_name': f'{namespace}::{enum_name}',
        'include': self.path_builder.EnumHeaderIncludePath(enum_name),
        'conditional': None,
        'is_callback_interface': False,
    }

  def referenced_class_contexts(self,
                                interface_names,
                                include_bindings_class=True):
    """Returns a list of jinja contexts describing referenced C++ classes.

    Args:
      interface_names: A list of interfaces.
      include_bindings_class: Include headers and classes uses only in bindings.
    Returns:
      list() of jinja contexts (python dicts) with information about C++ classes
      related to the interfaces in |interface_names|. dict has the following
      keys:
          fully_qualified_name: Fully qualified name of the class.
          include: Path to the header that defines the class.
          conditional: Symbol on which this interface is conditional compiled.
          is_callback_interface: True iff this is a callback interface.
    """
    referenced_classes = []
    # Iterate over it as a set to uniquify the list.
    for interface_name in set(interface_names):
      if interface_name in self.info_provider.enumerations:
        # If this is an enumeration, get the enum context and continue.
        referenced_classes.append(self.referenced_enum_context(interface_name))
        continue

      interface_info = self.info_provider.interfaces_info[interface_name]
      if interface_info['is_dictionary']:
        referenced_classes.append(
            self.referenced_dictionary_context(interface_name, interface_info))
      else:
        namespace = '::'.join(
            self.path_builder.NamespaceComponents(interface_name))
        conditional = interface_info['conditional']
        is_callback_interface = interface_name in IdlType.callback_interfaces
        impl_name = interface_info.get('implemented_as') or interface_name
        referenced_classes.append({
            'fully_qualified_name':
                f'{namespace}::{impl_name}',
            'include':
                self.path_builder.ImplementationHeaderPath(interface_name),
            'conditional':
                conditional,
            'is_callback_interface':
                is_callback_interface,
        })
        if include_bindings_class:
          referenced_classes.append({
              'fully_qualified_name':
                  f'{namespace}::{self.path_builder.BindingsClass(impl_name)}',
              'include':
                  self.path_builder.BindingsHeaderIncludePath(interface_name),
              'conditional':
                  conditional,
              'is_callback_interface':
                  is_callback_interface,
          })
    return referenced_classes

  def common_context(self, template):
    """Shared stuff."""
    # Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
    module_path_pyname = os.path.join(
        module_path,
        os.path.splitext(module_filename)[0] + '.py')

    # Ensure that posix forward slashes are used
    context = {
        'today':
            date.today(),
        'code_generator':
            normalize_slashes(os.path.relpath(module_path_pyname, cobalt_dir)),
        'template_path':
            normalize_slashes(os.path.relpath(template.filename, cobalt_dir)),
        'generated_conversion_include':
            self.path_builder.generated_conversion_include_path,
    }
    return context

  def build_dictionary_context(self, dictionary, for_conversion):
    context_builder = ContextBuilder(self.info_provider)
    context = {
        'class_name':
            dictionary.name,
        'header_file':
            self.path_builder.DictionaryHeaderIncludePath(dictionary.name),
        'members': [
            context_builder.get_dictionary_member_context(dictionary, member)
            for member in dictionary.members
        ]
    }
    referenced_interface_names = set(
        get_interface_type_names_from_typed_objects(self.info_provider,
                                                    dictionary.members))
    if dictionary.parent:
      referenced_interface_names.add(dictionary.parent)
      parent_namespace = '::'.join(
          self.path_builder.NamespaceComponents(dictionary.parent))
      context['parent'] = f'{parent_namespace}::{dictionary.parent}'

    referenced_class_contexts = self.referenced_class_contexts(
        referenced_interface_names, for_conversion)

    context['includes'] = sorted(
        interface['include'] for interface in referenced_class_contexts)
    context['forward_declarations'] = sorted(
        referenced_class_contexts, key=lambda x: x['fully_qualified_name'])
    context['components'] = self.path_builder.NamespaceComponents(
        dictionary.name)
    return context

  def build_interface_context(self, interface, interface_info, definitions):
    context_builder = ContextBuilder(self.info_provider)
    impl_class = interface.extended_attributes.get('ImplementedAs',
                                                   interface.name)

    context = {
        # Parameters used for template rendering.
        'today':
            date.today(),
        'binding_class':
            self.path_builder.BindingsClass(impl_class),
        'fully_qualified_binding_class':
            self.path_builder.FullBindingsClassName(impl_class, interface.name),
        'header_file':
            self.path_builder.BindingsHeaderIncludePath(interface.name),
        'impl_class':
            impl_class,
        'fully_qualified_impl_class':
            self.path_builder.FullClassName(impl_class, interface.name),
        'interface_name':
            interface.name,
        'is_global_interface':
            is_global_interface(interface),
        'has_interface_object': ('NoInterfaceObject'
                                 not in interface.extended_attributes),
        'conditional':
            interface.extended_attributes.get('Conditional', None),
    }
    interfaces_info = self.info_provider.interfaces_info
    if is_global_interface(interface):
      # Global interface references all interfaces.
      referenced_interface_names = set(
          interface_name for interface_name in interfaces_info['all_interfaces']
          if not interfaces_info[interface_name]['unsupported'] and
          not interfaces_info[interface_name]['is_callback_interface'] and
          not interfaces_info[interface_name]['is_dictionary'])
      referenced_interface_names.update(IdlType.callback_interfaces)
    else:
      # Build the set of referenced interfaces from this interface's members.
      referenced_interface_names = set(
          get_interface_type_names_from_typed_objects(self.info_provider,
                                                      interface.attributes))
      referenced_interface_names.update(
          get_interface_type_names_from_typed_objects(self.info_provider,
                                                      interface.operations))
      referenced_interface_names.update(
          get_interface_type_names_from_typed_objects(self.info_provider,
                                                      interface.constructors))
      referenced_interface_names.update(
          get_interface_type_names_from_typed_objects(
              self.info_provider, definitions.callback_functions.values()))

    # Build the set of #includes in the header file. Try to keep this small
    # to avoid circular dependency problems.
    header_includes = set()
    if interface.parent:
      header_includes.add(
          self.path_builder.BindingsHeaderIncludePath(interface.parent))
      referenced_interface_names.add(interface.parent)
    header_includes.add(
        self.path_builder.ImplementationHeaderPath(interface.name))

    attributes = [
        context_builder.attribute_context(interface, attribute, definitions)
        for attribute in interface.attributes
    ]
    constructor = context_builder.get_constructor_context(
        self.expression_generator, interface)
    methods = context_builder.get_method_contexts(self.expression_generator,
                                                  interface)
    constants = [
        context_builder.constant_context(c) for c in interface.constants
    ]

    # Get a list of all the unsupported property names, and remove the
    # unsupported ones from their respective lists
    attributes, unsupported_attribute_names = split_unsupported_properties(
        attributes)
    methods, unsupported_method_names = split_unsupported_properties(methods)
    constants, unsupported_constant_names = split_unsupported_properties(
        constants)

    # Build a set of all interfaces referenced by this interface.
    referenced_class_contexts = self.referenced_class_contexts(
        referenced_interface_names)

    all_interfaces = []
    for interface_name in referenced_interface_names:
      if (interface_name not in IdlType.callback_interfaces and
          interface_name not in IdlType.enums and
          not interfaces_info[interface_name]['unsupported'] and
          not interfaces_info[interface_name]['is_dictionary']):
        interface_info = interfaces_info[interface_name]
        all_interfaces.append({
            'impl_name': (interface_info.get('implemented_as') or
                          interface_name),
            'name': interface_name,
            'conditional': interface_info['conditional'],
        })

    context['implementation_includes'] = sorted(
        (interface['include'] for interface in referenced_class_contexts))
    context['header_includes'] = sorted(header_includes)
    context['attributes'] = [a for a in attributes if not a['is_static']]
    context['static_attributes'] = [a for a in attributes if a['is_static']]
    context['constants'] = constants
    context['constructor'] = constructor
    context['named_constructor'] = interface.extended_attributes.get(
        'NamedConstructor', None)
    context['interface'] = interface
    context['operations'] = [m for m in methods if not m['is_static']]
    context['static_operations'] = [m for m in methods if m['is_static']]
    context['unsupported_interface_properties'] = set(
        unsupported_attribute_names + unsupported_method_names +
        unsupported_constant_names)
    context['unsupported_constructor_properties'] = set(
        unsupported_constant_names)
    if interface.parent:
      context['parent_interface'] = self.path_builder.BindingsClass(
          interface.parent)
      context['parent_interface_name'] = interface.parent
    context['is_exception_interface'] = interface.is_exception
    context['forward_declarations'] = sorted(
        referenced_class_contexts, key=lambda x: x['fully_qualified_name'])
    context['all_interfaces'] = sorted(all_interfaces, key=lambda x: x['name'])
    context['callback_functions'] = definitions.callback_functions.values()
    context['enumerations'] = [
        context_builder.enumeration_context(enumeration)
        for enumeration in definitions.enumerations.values()
    ]
    context['components'] = self.path_builder.NamespaceComponents(
        interface.name)

    context['stringifier'] = context_builder.stringifier_context(interface)
    context['indexed_property_getter'] = context_builder.special_method_context(
        interface, get_indexed_property_getter(interface))
    context['indexed_property_setter'] = context_builder.special_method_context(
        interface, get_indexed_property_setter(interface))
    context[
        'indexed_property_deleter'] = context_builder.special_method_context(
            interface, get_indexed_property_deleter(interface))
    context['named_property_getter'] = context_builder.special_method_context(
        interface, get_named_property_getter(interface))
    context['named_property_setter'] = context_builder.special_method_context(
        interface, get_named_property_setter(interface))
    context['named_property_deleter'] = context_builder.special_method_context(
        interface, get_named_property_deleter(interface))

    context['supports_indexed_properties'] = (
        context['indexed_property_getter'] or
        context['indexed_property_setter'])
    context['supports_named_properties'] = (
        context['named_property_setter'] or context['named_property_getter'] or
        context['named_property_deleter'])

    names = sorted(list(interfaces_info))
    context['unique_id'] = names.index(interface.name)

    return context


################################################################################


def main(argv):
  # If file itself executed, cache templates
  try:
    cache_dir = argv[1]
    templates_dir = argv[2]
    dummy_filename = argv[3]
  except IndexError:
    print(f'Usage: {argv[0]} CACHE_DIR TEMPLATES_DIR DUMMY_FILENAME')
    return 1

  # Delete all jinja2 .cache files, since they will get regenerated anyways.
  for filename in os.listdir(cache_dir):
    if os.path.splitext(filename)[1] == '.cache':
      # We expect that the only .cache files in this directory are for jinja2
      # and they have a __jinja2_ prefix.
      assert filename.startswith('__jinja2_')
      os.remove(os.path.join(cache_dir, filename))

  # Cache templates.
  # Whether the path is absolute or relative affects the cache file name. Use
  # the absolute path to ensure that the same path is used when we populate the
  # cache here and when it's read during code generation.
  jinja_env = initialize_jinja_env(cache_dir, os.path.abspath(templates_dir))
  template_filenames = [
      filename for filename in os.listdir(templates_dir)
      # Skip .svn, directories, etc.
      if filename.endswith(('.template'))
  ]
  assert template_filenames, 'Expected at least one template to be cached.'
  shared_template_filenames = [
      filename for filename in os.listdir(SHARED_TEMPLATES_DIR)
      # Skip .svn, directories, etc.
      if filename.endswith(('.template'))
  ]
  for template_filename in template_filenames + shared_template_filenames:
    jinja_env.get_template(template_filename)

  # Create a dummy file as output for the build system,
  # since filenames of individual cache files are unpredictable and opaque
  # (they are hashes of the template path, which varies based on environment)
  with open(dummy_filename, 'w', encoding='utf-8') as dummy_file:
    pass  # |open| creates or touches the file


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