#!/usr/bin/python
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""This is the entry point to create Dart APIs from the IDL database."""

import css_code_generator
import os
import sys

# Setup all paths to find our PYTHON code

# dart_dir is the location of dart's enlistment dartium (dartium-git/src/dart)
# and Dart (dart-git/dart).
dart_dir = os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
sys.path.insert(1, os.path.join(dart_dir, 'tools/dom/new_scripts'))
sys.path.insert(1, os.path.join(dart_dir, 'third_party/WebCore/bindings/scripts'))

# Dartium's third_party directory location is dartium-git/src/third_party
# and Dart's third_party directory location is dart-git/dart/third_party.
third_party_dir = os.path.join(dart_dir, 'third_party')

ply_dir = os.path.join(third_party_dir, 'ply')
# If ply directory found then we're a Dart enlistment; third_party location
# is dart-git/dart/third_party
if not os.path.exists(ply_dir):
  # For Dartium (ply directory is dartium-git/src/third_party/ply) third_party
  # location is dartium-git/src/third_party 
  third_party_dir = os.path.join(dart_dir, '..', 'third_party')
  assert(os.path.exists(third_party_dir))
sys.path.insert(1, third_party_dir)

sys.path.insert(1, os.path.join(dart_dir, 'tools/dom/scripts'))

import dartgenerator
import database
import fremontcutbuilder
import logging
import monitored
import multiemitter
import optparse
import shutil
import subprocess
import time
from dartmetadata import DartMetadata
from generator import TypeRegistry
from htmleventgenerator import HtmlEventGenerator
from htmlrenamer import HtmlRenamer
from systemhtml import DartLibraryEmitter, Dart2JSBackend,\
                       HtmlDartInterfaceGenerator, DartLibrary, DartLibraries,\
                       HTML_LIBRARY_NAMES
from systemnative import CPPLibraryEmitter, DartiumBackend
from templateloader import TemplateLoader

sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))

import utils


_logger = logging.getLogger('dartdomgenerator')

class GeneratorOptions(object):
  def __init__(self, templates, database, type_registry, renamer,
      metadata, dart_js_interop):
    self.templates = templates
    self.database = database
    self.type_registry = type_registry
    self.renamer = renamer
    self.metadata = metadata;
    self.dart_js_interop = dart_js_interop

def LoadDatabase(database_dir, use_database_cache):
  common_database = database.Database(database_dir)
  if use_database_cache:
    common_database.LoadFromCache()
  else:
    common_database.Load()
  return common_database

def GenerateFromDatabase(common_database, dart2js_output_dir,
                         dartium_output_dir, update_dom_metadata=False,
                         logging_level=logging.WARNING, dart_js_interop=False):
  print '\n ----- Accessing DOM using %s -----\n' % ('dart:js' if dart_js_interop else 'C++')

  start_time = time.time()

  current_dir = os.path.dirname(__file__)
  auxiliary_dir = os.path.join(current_dir, '..', 'src')
  template_dir = os.path.join(current_dir, '..', 'templates')

  _logger.setLevel(logging_level)

  generator = dartgenerator.DartGenerator(logging_level)
  generator.LoadAuxiliary(auxiliary_dir)

  generator.FilterMembersWithUnidentifiedTypes(common_database)
  webkit_database = common_database.Clone()

  # Generate Dart interfaces for the WebKit DOM.
  generator.FilterInterfaces(database = webkit_database,
                             or_annotations = ['WebKit', 'Dart'],
                             exclude_displaced = ['WebKit'],
                             exclude_suppressed = ['WebKit', 'Dart'])
  generator.FixEventTargets(webkit_database)
  generator.AddMissingArguments(webkit_database)

  emitters = multiemitter.MultiEmitter(logging_level)
  metadata = DartMetadata(
      os.path.join(current_dir, '..', 'dom.json'),
      os.path.join(current_dir, '..', 'docs', 'docs.json'),
      logging_level)
  renamer = HtmlRenamer(webkit_database, metadata)
  type_registry = TypeRegistry(webkit_database, renamer)

  print 'GenerateFromDatabase %s seconds' % round((time.time() - start_time), 2)

  def RunGenerator(dart_libraries, dart_output_dir,
                   template_loader, backend_factory, dart_js_interop):
    options = GeneratorOptions(
        template_loader, webkit_database, type_registry, renamer,
        metadata, dart_js_interop)
    dart_library_emitter = DartLibraryEmitter(
        emitters, dart_output_dir, dart_libraries)
    event_generator = HtmlEventGenerator(webkit_database, renamer, metadata,
        template_loader)

    def generate_interface(interface):
      backend = backend_factory(interface)
      interface_generator = HtmlDartInterfaceGenerator(
          options, dart_library_emitter, event_generator, interface, backend)
      interface_generator.Generate()

    generator.Generate(webkit_database, common_database, generate_interface)

    dart_library_emitter.EmitLibraries(auxiliary_dir, dart_js_interop)

  if dart2js_output_dir:
    template_paths = ['html/dart2js', 'html/impl', 'html/interface', '']
    template_loader = TemplateLoader(template_dir,
                                     template_paths,
                                     {'DARTIUM': False,
                                      'DART2JS': True,
                                      'JSINTEROP': False})
    backend_options = GeneratorOptions(
        template_loader, webkit_database, type_registry, renamer,
        metadata, dart_js_interop)
    backend_factory = lambda interface:\
        Dart2JSBackend(interface, backend_options, logging_level)

    dart_output_dir = os.path.join(dart2js_output_dir, 'dart')
    dart_libraries = DartLibraries(
        HTML_LIBRARY_NAMES, template_loader, 'dart2js', dart2js_output_dir, dart_js_interop)

    print '\nGenerating dart2js:\n'
    start_time = time.time()

    RunGenerator(dart_libraries, dart_output_dir, template_loader,
                 backend_factory, dart_js_interop)

    print 'Generated dart2js in %s seconds' % round(time.time() - start_time, 2)

  if dartium_output_dir:
    template_paths = ['html/dartium', 'html/impl', 'html/interface', '']
    template_loader = TemplateLoader(template_dir,
                                     template_paths,
                                     {'DARTIUM': True,
                                      'DART2JS': False,
                                      'JSINTEROP': dart_js_interop})
    backend_options = GeneratorOptions(
        template_loader, webkit_database, type_registry, renamer,
        metadata, dart_js_interop)
    cpp_output_dir = os.path.join(dartium_output_dir, 'cpp')
    cpp_library_emitter = CPPLibraryEmitter(emitters, cpp_output_dir)
    dart_output_dir = os.path.join(dartium_output_dir, 'dart')
    backend_factory = lambda interface:\
        DartiumBackend(interface, cpp_library_emitter, backend_options)
    dart_libraries = DartLibraries(
        HTML_LIBRARY_NAMES, template_loader, 'dartium', dartium_output_dir, dart_js_interop)

    print '\nGenerating dartium:\n'
    start_time = time.time()

    RunGenerator(dart_libraries, dart_output_dir, template_loader,
                 backend_factory, dart_js_interop)
    print 'Generated dartium in %s seconds' % round(time.time() - start_time, 2)

    cpp_library_emitter.EmitDerivedSources(
        template_loader.Load('cpp_derived_sources.template'),
        dartium_output_dir)
    cpp_library_emitter.EmitResolver(
        template_loader.Load('cpp_resolver.template'), dartium_output_dir)
    cpp_library_emitter.EmitClassIdTable(
        webkit_database, dartium_output_dir, type_registry, renamer)
    emitters.Flush()

  if update_dom_metadata:
    metadata.Flush()

  monitored.FinishMonitoring(dart2js_output_dir, _logger)

def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
  library_dir = os.path.dirname(library_path)
  library_filename = os.path.basename(library_path)
  copy_dart_script = os.path.relpath('../../copy_dart.py',
      library_dir)
  output_dir = os.path.relpath(output_dir, library_dir)
  command = ' '.join(['cd', library_dir, ';',
                      copy_dart_script, output_dir, library_filename])
  subprocess.call([command], shell=True)

def UpdateCssProperties():
  """Regenerate the CssStyleDeclaration template file with the current CSS
  properties."""
  _logger.info('Updating Css Properties.')
  css_code_generator.GenerateCssTemplateFile()

def main():
  parser = optparse.OptionParser()
  parser.add_option('--parallel', dest='parallel',
                    action='store_true', default=False,
                    help='Use fremontcut in parallel mode.')
  parser.add_option('--systems', dest='systems',
                    action='store', type='string',
                    default='htmldart2js,htmldartium',
                    help='Systems to generate (htmldart2js, htmldartium)')
  parser.add_option('--output-dir', dest='output_dir',
                    action='store', type='string',
                    default=None,
                    help='Directory to put the generated files')
  parser.add_option('--use-database-cache', dest='use_database_cache',
                    action='store_true',
                    default=False,
                    help='''Use the cached database from the previous run to
                    improve startup performance''')
  parser.add_option('--update-dom-metadata', dest='update_dom_metadata',
                    action='store_true',
                    default=False,
                    help='''Update the metadata list of DOM APIs''')
  parser.add_option('--verbose', dest='logging_level',
                    action='store_false', default=logging.WARNING,
                    help='Output all informational messages')
  parser.add_option('--examine', dest='examine_idls',
                    action='store_true', default=None,
                    help='Analyze IDL files')
  parser.add_option('--logging', dest='logging', type='int',
                    action='store', default=logging.NOTSET,
                    help='Level of logging 20 is Info, 30 is Warnings, 40 is Errors')
  parser.add_option('--gen-interop', dest='dart_js_interop',
                    action='store_true', default=False,
                    help='Use Javascript objects (dart:js) accessing the DOM in _blink')

  (options, args) = parser.parse_args()

  current_dir = os.path.dirname(__file__)
  database_dir = os.path.join(current_dir, '..', 'database')
  logging.config.fileConfig(os.path.join(current_dir, 'logging.conf'))
  systems = options.systems.split(',')

  output_dir = options.output_dir or os.path.join(
      current_dir, '..', '..', utils.GetBuildDir(utils.GuessOS()),
      'generated')

  dart2js_output_dir = None
  if 'htmldart2js' in systems:
    dart2js_output_dir = os.path.join(output_dir, 'dart2js')
  dartium_output_dir = None
  if 'htmldartium' in systems:
    dartium_output_dir = os.path.join(output_dir, 'dartium')

  logging_level = options.logging_level \
    if options.logging == logging.NOTSET else options.logging

  start_time = time.time()

  UpdateCssProperties()

  # Parse the IDL and create the database.
  database = fremontcutbuilder.main(options.parallel, logging_level=logging_level, examine_idls=options.examine_idls)

  GenerateFromDatabase(database, dart2js_output_dir, dartium_output_dir,
      options.update_dom_metadata, logging_level, options.dart_js_interop)

  file_generation_start_time = time.time()

  if 'htmldart2js' in systems:
    _logger.info('Generating dart2js single files.')

    for library_name in HTML_LIBRARY_NAMES:
      GenerateSingleFile(
          os.path.join(dart2js_output_dir, '%s_dart2js.dart' % library_name),
          os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dart2js'))

  if 'htmldartium' in systems:
    _logger.info('Generating dartium single files.')
    file_generation_start_time = time.time()

    for library_name in HTML_LIBRARY_NAMES:
      GenerateSingleFile(
          os.path.join(dartium_output_dir, '%s_dartium.dart' % library_name),
          os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dartium'))

  print '\nGenerating single file %s seconds' % round(time.time() - file_generation_start_time, 2)

  end_time = time.time()

  print '\nDone (dartdomgenerator) %s seconds' % round(end_time - start_time, 2)

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