#!/usr/bin/env python3
# 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 WebCore is 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.
    sys.path.insert(1, os.path.join(dart_dir, 'third_party/WebCore'))

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,
                         generate_static_extensions=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.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, generate_static_extensions)

        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)
    dart_bin = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
    sdk_file = os.path.join(library_dir, output_dir, library_filename)
    formatCommand = ' '.join([dart_bin, 'format', 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')
    parser.add_option(
        '--generate-static-extensions',
        dest='generate_static_extensions',
        action='store_true',
        default=False,
        help='Generate static extension members for dart:html classes')

    (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,
                         options.generate_static_extensions)

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