#!/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))
else:
    # It's Dart we need to make sure that tools in injected in our search path
    # because this is where idl_parser is located for a Dart enlistment.  Dartium
    # can figure out the tools directory because of the location of where the
    # scripts blink scripts are located.
    tools_dir = os.path.join(dart_dir, 'tools')
    sys.path.insert(1, tools_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 generate_blink_file import Generate_Blink
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,
                         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)
    generator.CleanupOperationArguments(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, gl_constants=None):
            backend = backend_factory(interface)
            interface_generator = HtmlDartInterfaceGenerator(
                options, dart_library_emitter, event_generator, interface,
                backend)
            interface_generator.Generate()
            if len(backend._gl_constants) > 0 and not (gl_constants is None):
                gl_constants.extend(backend._gl_constants)

        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,
            'NNBD': True,
        })
        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)
        for file in generator._auxiliary_files.values():
            if file.endswith('darttemplate'):
                dart_libraries._libraries['html'].AddFile(file)

        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)

    emitters.Flush()

    if update_dom_metadata:
        metadata.Flush()

    monitored.FinishMonitoring(dart2js_output_dir, _logger)


def GenerateSingleFile(library_path, output_dir, generated_output_dir=None, prefix=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)
    if not os.path.exists(library_dir):
        os.makedirs(library_dir)
    prefix_arg = 'export DART_HTML_PREFIX="' + prefix + '";' if prefix else ""
    command = ' '.join([
        prefix_arg, 'cd', library_dir, ';', copy_dart_script, output_dir, library_filename
    ])
    subprocess.call([command], shell=True)
    prebuilt_dartfmt = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dartfmt')
    sdk_file = os.path.join(library_dir, output_dir, library_filename)
    formatCommand = ' '.join([prebuilt_dartfmt, '-w', sdk_file])
    subprocess.call([formatCommand], shell=True)


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


CACHED_PATCHES = """
// START_OF_CACHED_PATCHES
// Copyright (c) 2013, 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.

// DO NOT EDIT GENERATED FILE.

library cached_patches;

var cached_patches = {
    /********************************************************
     *****                                              *****
     *****  MUST RUN tools/dartium/generate_patches.sh  *****
     *****                                              *****
     ********************************************************/
};
"""


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,_blink',
        help='Systems to generate (htmldart2js, htmldartium, _blink)')
    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')
    parser.add_option(
        '--no-cached-patches',
        dest='no_cached_patches',
        action='store_true',
        default=False,
        help='Do not generate the sdk/lib/js/cached_patches.dart file')

    (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')

    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,
                         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:
            source = os.path.join(dart2js_output_dir,
                                  '%s_dart2js.dart' % library_name)
            GenerateSingleFile(
                source, os.path.join('..', '..', '..', 'sdk', 'lib',
                                     library_name, 'dart2js'))

    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())
