#!/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.

import database
import databasebuilder
import idlparser
import logging.config
import os.path
import sys

# TODO(antonm): most probably should go away or be autogenerated on IDLs roll.
DEFAULT_FEATURE_DEFINES = [
    # Enabled Chrome WebKit build.
    'ENABLE_3D_PLUGIN',
    'ENABLE_3D_RENDERING',
    'ENABLE_ACCELERATED_2D_CANVAS',
    'ENABLE_BATTERY_STATUS',
    'ENABLE_BLOB',
    'ENABLE_BLOB_SLICE',
    'ENABLE_CALENDAR_PICKER',
    'ENABLE_CHANNEL_MESSAGING',
    'ENABLE_CSS_FILTERS',
    'ENABLE_CSS_IMAGE_SET',
    'ENABLE_CSS_SHADERS',
    # 'ENABLE_DART',
    'ENABLE_DATA_TRANSFER_ITEMS',
    'ENABLE_DATALIST_ELEMENT',
    'ENABLE_DETAILS',
    'ENABLE_DETAILS_ELEMENT',
    'ENABLE_DEVICE_ORIENTATION',
    'ENABLE_DIRECTORY_UPLOAD',
    'ENABLE_DOWNLOAD_ATTRIBUTE',
    'ENABLE_ENCRYPTED_MEDIA',
    'ENABLE_FILE_SYSTEM',
    'ENABLE_FILTERS',
    'ENABLE_FULLSCREEN_API',
    'ENABLE_GAMEPAD',
    'ENABLE_GEOLOCATION',
    'ENABLE_GESTURE_EVENTS',
    'ENABLE_INDEXED_DATABASE',
    'ENABLE_INPUT_SPEECH',
    'ENABLE_INPUT_TYPE_COLOR',
    'ENABLE_INPUT_TYPE_DATE',
    'ENABLE_JAVASCRIPT_DEBUGGER',
    'ENABLE_JAVASCRIPT_I18N_API',
    'ENABLE_LEGACY_NOTIFICATIONS',
    'ENABLE_LINK_PREFETCH',
    'ENABLE_MEDIA_SOURCE',
    'ENABLE_MEDIA_STATISTICS',
    'ENABLE_MEDIA_STREAM',
    'ENABLE_METER_ELEMENT',
    'ENABLE_METER_TAG',
    'ENABLE_MHTML',
    'ENABLE_MUTATION_OBSERVERS',
    'ENABLE_NOTIFICATIONS',
    'ENABLE_OVERFLOW_SCROLLING',
    'ENABLE_PAGE_POPUP',
    'ENABLE_PAGE_VISIBILITY_API',
    'ENABLE_POINTER_LOCK',
    'ENABLE_PROGRESS_ELEMENT',
    'ENABLE_PROGRESS_TAG',
    'ENABLE_QUOTA',
    'ENABLE_REGISTER_PROTOCOL_HANDLER',
    'ENABLE_REQUEST_ANIMATION_FRAME',
    'ENABLE_RUBY',
    'ENABLE_SANDBOX',
    'ENABLE_SCRIPTED_SPEECH',
    'ENABLE_SHADOW_DOM',
    'ENABLE_SHARED_WORKERS',
    'ENABLE_SMOOTH_SCROLLING',
    'ENABLE_SQL_DATABASE',
    'ENABLE_STYLE_SCOPED',
    'ENABLE_SVG',
    'ENABLE_SVG_FONTS',
    'ENABLE_TOUCH_EVENTS',
    'ENABLE_V8_SCRIPT_DEBUG_SERVER',
    'ENABLE_VIDEO',
    'ENABLE_VIDEO_TRACK',
    'ENABLE_VIEWPORT',
    'ENABLE_WEBGL',
    'ENABLE_WEB_AUDIO',
    'ENABLE_WEB_INTENTS',
    'ENABLE_WEB_SOCKETS',
    'ENABLE_WEB_TIMING',
    'ENABLE_WORKERS',
    'ENABLE_XHR_RESPONSE_BLOB',
    'ENABLE_XSLT',
]

def build_database(idl_files, database_dir, feature_defines=None,
                   parallel=False):
  """This code reconstructs the FremontCut IDL database from W3C,
  and WebKit IDL files."""
  current_dir = os.path.dirname(__file__)
  logging.config.fileConfig(os.path.join(current_dir, "logging.conf"))

  db = database.Database(database_dir)

  # Delete all existing IDLs in the DB.
  db.Delete()

  builder = databasebuilder.DatabaseBuilder(db)

  # TODO(vsm): Move this to a README.
  # This is the Dart SVN revision.
  webkit_revision = '1060'

  # TODO(vsm): Reconcile what is exposed here and inside WebKit code
  # generation.  We need to recheck this periodically for now.
  webkit_defines = [ 'LANGUAGE_JAVASCRIPT' ]
  if feature_defines is None:
      feature_defines = DEFAULT_FEATURE_DEFINES

  webkit_options = databasebuilder.DatabaseBuilderOptions(
      idl_syntax=idlparser.WEBKIT_SYNTAX,
      # TODO(vsm): What else should we define as on when processing IDL?
      idl_defines=webkit_defines + feature_defines,
      source='WebKit',
      source_attributes={'revision': webkit_revision})

  # Import WebKit IDLs.
  builder.import_idl_files(idl_files, webkit_options, parallel)

  # Merging:
  builder.merge_imported_interfaces()

  builder.fetch_constructor_data(webkit_options)
  builder.fix_displacements('WebKit')

  # Cleanup:
  builder.normalize_annotations(['WebKit'])

  db.Save()
  return db

def main(parallel=False):
  current_dir = os.path.dirname(__file__)

  webkit_dirs = [
    'css',
    'dom',
    'fileapi',
    'html',
    'html/canvas',
    'inspector',
    'loader',
    'loader/appcache',
    'Modules/battery',
    'Modules/filesystem',
    'Modules/gamepad',
    'Modules/geolocation',
    'Modules/indexeddb',
    'Modules/mediasource',
    'Modules/mediastream',
    'Modules/notifications',
    'Modules/quota',
    'Modules/speech',
    'Modules/webaudio',
    'Modules/webdatabase',
    'Modules/websockets',
    'page',
    'plugins',
    'storage',
    'svg',
    'workers',
    'xml',
    ]

  ignored_idls = [
    'AbstractView.idl',
    ]

  idl_files = []

  webcore_dir = os.path.join(current_dir, '..', 'WebCore')
  if not os.path.exists(webcore_dir):
    raise RuntimeError('directory not found: %s' % webcore_dir)

  def visitor(arg, dir_name, names):
    for name in names:
      file_name = os.path.join(dir_name, name)
      (interface, ext) = os.path.splitext(file_name)
      if ext == '.idl' and name not in ignored_idls:
        idl_files.append(file_name)

  for dir_name in webkit_dirs:
    dir_path = os.path.join(webcore_dir, dir_name)
    os.path.walk(dir_path, visitor, None)

  # Include additional IDLs
  os.path.walk(os.path.join(current_dir, '..', 'idl'), visitor, None)

  database_dir = os.path.join(current_dir, '..', 'database')
  return build_database(idl_files, database_dir, parallel=parallel)

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