# 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.
"""Compile an .idl file to Cobalt bindings (.h and .cpp files).

Based on and uses blink's IDL compiler found in the blink repository at
third_party/blink/Source/bindings/scripts/idl_compiler.py.
"""

from optparse import OptionParser  # pylint: disable=deprecated-module
import os
import pickle

from idl_compiler import IdlCompiler
from utilities import ComponentInfoProviderCobalt
from utilities import idl_filename_to_interface_name
from utilities import write_file


def create_component_info_provider(interfaces_info_path, component_info_path):
  with open(os.path.join(interfaces_info_path), 'rb') as interface_info_file:
    interfaces_info = pickle.load(interface_info_file)
  with open(os.path.join(component_info_path), 'rb') as component_info_file:
    component_info = pickle.load(component_info_file)
  return ComponentInfoProviderCobalt(interfaces_info, component_info)


def parse_options():
  """Parse command line options. Based on parse_options in idl_compiler.py."""
  parser = OptionParser()
  parser.add_option(
      '--cache-directory', help='cache directory, defaults to output directory')
  parser.add_option('--output-directory')
  parser.add_option('--interfaces-info')
  parser.add_option('--component-info')
  parser.add_option(
      '--extended-attributes',
      help='file containing whitelist of supported extended attributes')

  options, args = parser.parse_args()
  if options.output_directory is None:
    parser.error('Must specify output directory using --output-directory.')
  if len(args) != 1:
    parser.error('Must specify exactly 1 input file as argument, '
                 f'but {len(args)} given.')
  idl_filename = os.path.realpath(args[0])
  return options, idl_filename


class IdlCompilerCobalt(IdlCompiler):
  """IDL Compiler for Cobalt."""

  def __init__(self, *args, **kwargs):
    IdlCompiler.__init__(self, *args, **kwargs)

  def compile_and_write(self, idl_filename):
    interface_name = idl_filename_to_interface_name(idl_filename)
    definitions = self.reader.read_idl_definitions(idl_filename)
    # Merge all component definitions into a single list, since we don't really
    # care about components in Cobalt.
    assert len(definitions) == 1
    output_code_list = self.code_generator.generate_code(
        list(definitions.values())[0], interface_name)

    # Generator may choose to omit the file.
    if output_code_list is None:
      return

    for output_path, output_code in output_code_list:
      write_file(output_code, output_path)


def generate_bindings(code_generator_class):
  """This will be called from the engine-specific idl_compiler.py script."""
  options, input_filename = parse_options()
  # |input_filename| should be a path of an IDL file.
  cobalt_info_provider = create_component_info_provider(options.interfaces_info,
                                                        options.component_info)
  idl_compiler = IdlCompilerCobalt(
      options.output_directory,
      cache_directory=options.cache_directory,
      code_generator_class=code_generator_class,
      info_provider=cobalt_info_provider,
      extended_attributes_filepath=options.extended_attributes)
  idl_compiler.compile_file(input_filename)
