#!/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 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())
