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