#!/usr/bin/python
#
# 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 sets import Set
from generator import AnalyzeOperation, AnalyzeConstructor

# 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([])

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 compatibile 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 and propertyQuery code
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 ConstantOutputOrder(a, b):
  """Canonical output ordering for constants."""
  return cmp(a.id, b.id)

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)

    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)

    blink_file.write(CLASS_DEFINITION_END);

  blink_file.write(BLINK_UTILS)

  blink_file.close()

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, 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):
  analyzeOperations = []

  for operation in sorted(operations, 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)
        analyzeOperations = [operation]
  if len(analyzeOperations) > 0:
    _Emit_Blink_Operation(blink_file, interface, analyzeOperations)

def _Emit_Blink_Operation(blink_file, interface, analyzeOperations):
  analyzed = AnalyzeOperation(interface, analyzeOperations)
  (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))
