#!/usr/bin/env python3
#
# Copyright (c) 2014, 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.
"""Generates sdk/lib/_blink/dartium/_blink_dartium.dart file."""

import os
from generator import AnalyzeOperation, AnalyzeConstructor, ConstantOutputOrder

# This is list of all methods with native c++ implementations
# If performing a dartium merge, the best practice is to comment out this list,
# ensure everything runs, and then uncomment this list which might possibly
# introduce breaking changes due to changes to these method signatures.
_js_custom_members = set([
    'Document.createElement',
    'Element.id',
    'Element.tagName',
    'Element.className',
    'Element.setAttribute',
    'Element.getAttribute',
    # Consider adding this method so there is a fast path to access only
    # element children.
    # 'NonDocumentTypeChildNode.nextElementSibling',
    'Node.appendChild',  # actually not removed, just native implementation.
    'Node.cloneNode',
    'Node.insertBefore',
    'Node.lastChild',
    'Node.firstChild',
    'Node.parentElement',
    'Node.parentNode',
    'Node.childNodes',
    'Node.removeChild',
    'Node.contains',
    'Node.nextSibling',
    'Node.previousSibling',
    'ChildNode.remove',
    'Document.createTextNode',
    'Window.location',
    'Location.href',
    'Location.hash',
    'Node.querySelector',
    'HTMLElement.hidden',
    'HTMLElement.style',
    'Element.attributes',
    'Window.innerWidth',
    'NodeList.length',
    'NodeList.item',
    'ParentNode.children',
    'ParentNode.firstElementChild',
    'ParentNode.lastElementChild',
    'Event.target',
    'MouseEvent.clientY',
    'MouseEvent.clientX',
    'Node.nodeType',
    'Node.textContent',
    'HTMLCollection.length',
    'HTMLCollection.item',
    'Node.lastElementChild',
    'Node.firstElementChild',
    'HTMLElement_tabIndex',
    'Element.clientWidth',
    'Element.clientHeight',
    'Document.body',
    'Element.removeAttribute',
    'Element.getBoundingClientRect',
    'CSSStyleDeclaration.getPropertyValue',
    'CSSStyleDeclaration.setProperty',
    'CSSStyleDeclaration.__propertyQuery__',

    # TODO(jacobr): consider implementing these methods as well as they show
    # up in benchmarks for some sample applications.
    #'Document.createEvent',
    #'Document.initEvent',
    #'EventTarget.dispatchEvent',
])

# Uncomment out this line  to short circuited native methods and run all of
# dart:html through JS interop except for createElement which is slightly more
# tightly natively wired.
# _js_custom_members = set()

# Expose built-in methods support by an instance that is not shown in the IDL.
_additional_methods = {
    # Support propertyIsEnumerable (available on all objects only needed by
    # CSSStyleDeclaration decides if style property is supported (handling
    # camelcase and inject hyphens between camelcase).
    # Format of dictionary is 'operation name', arguments, returns value (True or False)
    'CSSStyleDeclaration': ('propertyIsEnumerable', 1, True),
}

HEADER = """/* Copyright (c) 2014, 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
 * Auto-generated _blink library.
 */
library dart.dom._blink;

import 'dart:async';
import 'dart:js' as js;
import 'dart:html' show DomException;
import 'dart:_internal' as internal;
// This is a place to put custom renames if we need them.
final resolverMap = {
};

dynamic resolver(String s) {
"""

END_RESOLVER = """
  // Failed to find it, check for custom renames
  dynamic obj = resolverMap[s];
  if (obj != null) return obj;
  throw("No such interface exposed in blink: ${s}");
}

"""

BLINK_UTILS = """
// _Utils native entry points
class Blink_Utils {
  static window() native "Utils_window";

  static forwardingPrint(message) native "Utils_forwardingPrint";

  static spawnDomUri(uri) native "Utils_spawnDomUri";

  static void spawnDomHelper(Function f, int replyTo) native "Utils_spawnDomHelper";

  static register(document, tag, customType, extendsTagName) native "Utils_register";

  // Below code sets up VMLibraryHooks for resolvePackageUri.
  static Uri resolvePackageUri(Uri packageUri) native "Utils_resolvePackageUri";
  static Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
      return resolvePackageUri(packageUri);
  }
  static void _setupHooks() {
    internal.VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
  }

  // Defines an interceptor if there is an appropriate JavaScript prototype to define it on.
  // In any case, returns a typed JS wrapper compatible with dart:html and the new
  // typed JS Interop.
  static defineInterceptorCustomElement(jsObject, Type type) native "Utils_defineInterceptorCustomElement";
  static defineInterceptor(jsObject, Type type) native "Utils_defineInterceptor";
  static setInstanceInterceptor(o, Type type, {bool customElement: false}) native "Utils_setInstanceInterceptor";
  static setInstanceInterceptorCustomUpgrade(o) native "Utils_setInstanceInterceptorCustomUpgrade";

  // This method will throw if the element isn't actually a real Element.
  static initializeCustomElement(element) native "Utils_initializeCustomElement";
}

class Blink_DOMStringMap {
  // _DOMStringMap native entry  points
  static containsKey(_DOMStringMap, key) native "DOMStringMap_containsKey_Callback";

  static item(_DOMStringMap, key) native "DOMStringMap_item_Callback";

  static setItem(_DOMStringMap, key, value) native "DOMStringMap_setItem_Callback";

  static remove(_DOMStringMap, key) native "DOMStringMap_remove_Callback";

  static get_keys(_DOMStringMap) native "DOMStringMap_getKeys_Callback";
}

// Calls through JsNative but returns DomException instead of error strings.
class Stats {
  Stats(this.name) {
    counts = new Map<String, int>();
  }

  String name;
  Map<String, int> counts;
  clear() {
    counts.clear();
  }

  track(String v) {
    counts[v] = counts.putIfAbsent(v, ()=> 0) + 1;
  }
  toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('================');
    sb.write('$name ${counts.length}');
    var keys = counts.keys.toList();
    keys.sort((a,b) => counts[b].compareTo(counts[a]));
    for (var key in keys) {
      print("$key => ${counts[key]}");
    }
    sb.write('---------------');
    sb.write('================');
    return sb;
  }
}

bool TRACK_STATS = true;
dumpStats() {
  print("------------ STATS ----------------");
  print(Blink_JsNative_DomException.getPropertyStats.toString());
  print(Blink_JsNative_DomException.setPropertyStats.toString());
  print(Blink_JsNative_DomException.callMethodStats.toString());
  print(Blink_JsNative_DomException.constructorStats.toString());
  print("-----------------------------------");
}

clearStats() {
  Blink_JsNative_DomException.getPropertyStats.clear();
  Blink_JsNative_DomException.setPropertyStats.clear();
  Blink_JsNative_DomException.callMethodStats.clear();
  Blink_JsNative_DomException.constructorStats.clear();
}

class Blink_JsNative_DomException {
  static var getPropertyStats = new Stats('get property');
  static var setPropertyStats = new Stats('set property');
  static var callMethodStats = new Stats('call method');
  static var constructorStats = new Stats('constructor');

  static var constructors = new Map<String, dynamic>();

  static getProperty(o, String name) {
    try {
      if (TRACK_STATS) getPropertyStats.track(name);
      return js.JsNative.getProperty(o, name);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }

  static propertyQuery(o, String name) {
    try {
      if (TRACK_STATS) getPropertyStats.track('__propertyQuery__');
      return js.JsNative.getProperty(o, name);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }

  static callConstructor0(String name) {
    try {
      if (TRACK_STATS) constructorStats.track(name);
      var constructor = constructors.putIfAbsent(name, () => js.context[name]);
      return js.JsNative.callConstructor0(constructor);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }

  static callConstructor(String name, List args) {
    try {
      if (TRACK_STATS) constructorStats.track(name);
      var constructor = constructors.putIfAbsent(name, () => js.context[name]);
      return js.JsNative.callConstructor(constructor, args);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }

  static setProperty(o, String name, value) {
    try {
      if (TRACK_STATS) setPropertyStats.track(name);
      return js.JsNative.setProperty(o, name, value);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }

  static callMethod(o, String method, List args) {
    try {
      if (TRACK_STATS) callMethodStats.track(method);
      return js.JsNative.callMethod(o, method, args);
    } catch (e) {
      // Re-throw any errors (returned as a string) as a DomException.
      throw new DomException.jsInterop(e);
    }
  }
}"""

CLASS_DEFINITION = """class Blink%s {
  static final instance = new Blink%s();

"""

CLASS_DEFINITION_EXTENDS = """class Blink%s extends Blink%s {
  static final instance = new Blink%s();

"""

#(interface_name)

#
CONSTRUCTOR_0 = [
    '  constructorCallback_0_()',
    ' => Blink_JsNative_DomException.callConstructor0("%s");\n\n',
    ' native "Blink_Constructor_%s";\n\n'
]

#(argument_count, arguments, interface_name, arguments)
CONSTRUCTOR_ARGS = [
    '  constructorCallback_%s_(%s)',
    ' => Blink_JsNative_DomException.callConstructor("%s", [%s]);\n\n',
    ' native "Blink_Constructor_Args_%s" /* %s */;\n\n'
]

#(attribute_name, attribute_name)
ATTRIBUTE_GETTER = [
    '  %s_Getter_(mthis)',
    ' => Blink_JsNative_DomException.getProperty(mthis /* %s */, "%s");\n\n',
    ' native "Blink_Getter_%s_%s";\n\n'
]

ATTRIBUTE_SETTER = [
    '  %s_Setter_(mthis, __arg_0)',
    ' => Blink_JsNative_DomException.setProperty(mthis /* %s */, "%s", __arg_0);\n\n',
    ' native "Blink_Setter_%s_%s";\n\n'
]

#(operation_name, operationName)
OPERATION_0 = [
    '  %s_Callback_0_(mthis)',
    ' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", []);\n\n',
    ' native "Blink_Operation_0_%s_%s";\n\n'
]

# getter, setter, deleter, propertyQuery code, and propertyIsEnumerable
OPERATION_1 = [
    '  $%s_Callback_1_(mthis, __arg_0)',
    ' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [__arg_0]);\n\n',
    ' native "Blink_Operation_1_%s_%s";\n\n'
]

OPERATION_2 = [
    '  $%s_Callback_2_(mthis, __arg_0, __arg_1)',
    ' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [__arg_0, __arg_1]);\n\n',
    ' native "Blink_Operation_2_%s_%s";\n\n'
]

OPERATION_PQ = [
    '  $%s_Callback_1_(mthis, __arg_0)',
    ' => Blink_JsNative_DomException.propertyQuery(mthis, __arg_0); /* %s */ \n\n',
    ' native "Blink_Operation_PQ_%s";\n\n'
]

#(operation_name, argument_count, arguments, operation_name, arguments)
ARGUMENT_NUM = "__arg_%s"
OPERATION_ARGS = [
    '  %s_Callback_%s_(mthis, %s)',
    ' => Blink_JsNative_DomException.callMethod(mthis /* %s */, "%s", [%s]);\n\n',
    ' native "Blink_Operation_%s_%s"; /* %s */\n\n'
]

# get class property to make static call.
CLASS_STATIC = 'Blink_JsNative_DomException.getProperty(js.context, "%s")'

# name, classname_getproperty, name
STATIC_ATTRIBUTE_GETTER = [
    '  %s_Getter_()',
    ' => Blink_JsNative_DomException.getProperty(%s /* %s */, "%s");\n\n',
    ' /* %s */ native "Blink_Static_getter_%s_%s"'
]

# name, classname_getproperty, name
STATIC_OPERATION_0 = [
    '  %s_Callback_0_()',
    ' => Blink_JsNative_DomException.callMethod(%s /* %s */, "%s", []);\n\n',
    ' /* %s */ native "Blink_Static_Operation_0_%s_%s'
]

# name, argsCount, args, classname_getproperty, name, args
STATIC_OPERATION_ARGS = [
    '  %s_Callback_%s_(%s)',
    ' => Blink_JsNative_DomException.callMethod(%s /* %s */, "%s", [%s]);\n\n',
    ' /* %s */ native "Blink_Static_Operations_%s_%s" /* %s */ \n\n'
]

CLASS_DEFINITION_END = """}

"""

def generate_parameter_entries(param_infos):
    optional_default_args = 0
    for argument in param_infos:
        if argument.is_optional:
            optional_default_args += 1

    arg_count = len(param_infos)
    min_arg_count = arg_count - optional_default_args
    lb = min_arg_count - 2 if min_arg_count > 2 else 0
    return (lb, arg_count + 1)


constructor_renames = {
    'RTCPeerConnection': 'webkitRTCPeerConnection',
    'SpeechRecognition': 'webkitSpeechRecognition',
}


def rename_constructor(name):
    return constructor_renames[name] if name in constructor_renames else name


def _Find_Match(interface_id, member, member_prefix, candidates):
    member_name = interface_id + '.' + member
    if member_name in candidates:
        return member_name
    member_name = interface_id + '.' + member_prefix + member
    if member_name in candidates:
        return member_name
    member_name = interface_id + '.*'
    if member_name in candidates:
        return member_name


def _Is_Native(interface, member):
    return _Find_Match(interface, member, '', _js_custom_members)


def Select_Stub(template, is_native):
    if is_native:
        return template[0] + template[2]
    else:
        return template[0] + template[1]


def Generate_Blink(output_dir, database, type_registry):
    blink_filename = os.path.join(output_dir, '_blink_dartium.dart')
    blink_file = open(blink_filename, 'w')

    blink_file.write(HEADER)

    interfaces = database.GetInterfaces()
    for interface in interfaces:
        name = interface.id
        resolver_entry = '  if (s == "%s") return Blink%s.instance;\n' % (name,
                                                                          name)
        blink_file.write(resolver_entry)

    blink_file.write(END_RESOLVER)

    for interface in interfaces:
        name = interface.id

        if interface.parents and len(
                interface.parents) > 0 and interface.parents[0].id:
            extends = interface.parents[0].id
            class_def = CLASS_DEFINITION_EXTENDS % (name, extends, name)
        else:
            class_def = CLASS_DEFINITION % (name, name)
        blink_file.write(class_def)

        analyzed_constructors = AnalyzeConstructor(interface)
        if analyzed_constructors:
            _Emit_Blink_Constructors(blink_file, analyzed_constructors)
        elif 'Constructor' in interface.ext_attrs:
            # Zero parameter constructor.
            blink_file.write(
                Select_Stub(CONSTRUCTOR_0, _Is_Native(name, 'constructor')) %
                rename_constructor(name))

        _Process_Attributes(blink_file, interface, interface.attributes)
        _Process_Operations(blink_file, interface, interface.operations, True)

        _Emit_Extra_Operations(blink_file, name)

        secondary_parents = database.TransitiveSecondaryParents(
            interface, False)
        for secondary in secondary_parents:
            _Process_Attributes(blink_file, secondary, secondary.attributes)
            _Process_Operations(blink_file, secondary, secondary.operations,
                                False)

        blink_file.write(CLASS_DEFINITION_END)

    blink_file.write(BLINK_UTILS)

    blink_file.close()


def _Emit_Extra_Operations(blink_file, interface_name):
    if (interface_name in _additional_methods):
        (name, arg_count, return_value) = _additional_methods[interface_name]
        exposed_name = ''.join(['__get', '___', name]) if return_value else name
        blink_file.write(
            Select_Stub(OPERATION_1, False) % (exposed_name, interface_name,
                                               name))


def _Emit_Blink_Constructors(blink_file, analyzed_constructors):
    (arg_min_count, arg_max_count) = generate_parameter_entries(
        analyzed_constructors.param_infos)
    name = analyzed_constructors.js_name
    if not (name):
        name = analyzed_constructors.type_name

    for callback_index in range(arg_min_count, arg_max_count):
        if callback_index == 0:
            blink_file.write(
                Select_Stub(CONSTRUCTOR_0, _Is_Native(name, 'constructor')) %
                (rename_constructor(name)))
        else:
            arguments = []
            for i in range(0, callback_index):
                arguments.append(ARGUMENT_NUM % i)
            argument_list = ', '.join(arguments)
            blink_file.write(
                Select_Stub(CONSTRUCTOR_ARGS, _Is_Native(name, 'constructor')) %
                (callback_index, argument_list, rename_constructor(name),
                 argument_list))


def _Process_Attributes(blink_file, interface, attributes):
    # Emit an interface's attributes and operations.
    for attribute in sorted(attributes, key=ConstantOutputOrder):
        name = attribute.id
        is_native = _Is_Native(interface.id, name)
        if attribute.is_read_only:
            if attribute.is_static:
                class_property = CLASS_STATIC % interface.id
                blink_file.write(
                    Select_Stub(STATIC_ATTRIBUTE_GETTER, is_native) %
                    (name, class_property, interface.id, name))
            else:
                blink_file.write(
                    Select_Stub(ATTRIBUTE_GETTER, is_native) %
                    (name, interface.id, name))
        else:
            blink_file.write(
                Select_Stub(ATTRIBUTE_GETTER, is_native) % (name, interface.id,
                                                            name))
            blink_file.write(
                Select_Stub(ATTRIBUTE_SETTER, is_native) % (name, interface.id,
                                                            name))


def _Process_Operations(blink_file,
                        interface,
                        operations,
                        primary_interface=False):
    analyzeOperations = []

    for operation in sorted(operations, key=ConstantOutputOrder):
        if len(analyzeOperations) == 0:
            analyzeOperations.append(operation)
        else:
            if analyzeOperations[0].id == operation.id:
                # Handle overloads
                analyzeOperations.append(operation)
            else:
                _Emit_Blink_Operation(blink_file, interface, analyzeOperations,
                                      primary_interface)
                analyzeOperations = [operation]
    if len(analyzeOperations) > 0:
        _Emit_Blink_Operation(blink_file, interface, analyzeOperations,
                              primary_interface)


# List of DartName operations to not emit (e.g., For now only WebGL2RenderingContextBase
# has readPixels in both WebGLRenderingContextBase and WebGL2RenderingContextBase.
# Furthermore, readPixels has the exact same number of arguments - in Javascript
# there is no typing so they're the same.
suppressed_operations = {
    'WebGL2RenderingContextBase': ['readPixels2', 'texImage2D2'],
}


def _Suppress_Secondary_Interface_Operation(interface, analyzed):
    if interface.id in suppressed_operations:
        # Should this DartName (name property) be suppressed on this interface?
        return analyzed.name in suppressed_operations[interface.id]
    return False


def _Emit_Blink_Operation(blink_file, interface, analyzeOperations,
                          primary_interface):
    analyzed = AnalyzeOperation(interface, analyzeOperations)

    if not (primary_interface) and _Suppress_Secondary_Interface_Operation(
            interface, analyzed):
        return

    (arg_min_count,
     arg_max_count) = generate_parameter_entries(analyzed.param_infos)
    name = analyzed.js_name

    is_native = _Is_Native(interface.id, name)

    operation = analyzeOperations[0]
    if (name.startswith('__') and \
        ('getter' in operation.specials or \
         'setter' in operation.specials or \
         'deleter' in operation.specials)):
        if name == '__propertyQuery__':
            blink_file.write(
                Select_Stub(OPERATION_PQ, is_native) % (name, interface.id))
        else:
            arg_min_count = arg_max_count
            if arg_max_count == 2:
                blink_file.write(
                    Select_Stub(OPERATION_1, is_native) % (name, interface.id,
                                                           name))
            elif arg_max_count == 3:
                blink_file.write(
                    Select_Stub(OPERATION_2, is_native) % (name, interface.id,
                                                           name))
            else:
                print("FATAL ERROR: _blink emitter operator %s.%s" %
                      (interface.id, name))
                exit

        return

    for callback_index in range(arg_min_count, arg_max_count):
        if callback_index == 0:
            if operation.is_static:
                class_property = CLASS_STATIC % interface.id
                blink_file.write(
                    Select_Stub(STATIC_OPERATION_0, is_native) %
                    (name, class_property, interface.id, name))
            else:
                blink_file.write(
                    Select_Stub(OPERATION_0, is_native) % (name, interface.id,
                                                           name))
        else:
            arguments = []
            for i in range(0, callback_index):
                arguments.append(ARGUMENT_NUM % i)
            argument_list = ', '.join(arguments)
            if operation.is_static:
                class_property = CLASS_STATIC % interface.id
                blink_file.write(
                    Select_Stub(STATIC_OPERATION_ARGS, is_native) %
                    (name, callback_index, argument_list, class_property,
                     interface.id, name, argument_list))
            else:
                blink_file.write(
                    Select_Stub(OPERATION_ARGS, is_native) %
                    (name, callback_index, argument_list, interface.id, name,
                     argument_list))
