// 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.

library dart._js_names;

import 'dart:_js_embedded_names'
    show JsGetName, MANGLED_GLOBAL_NAMES, MANGLED_NAMES;

import 'dart:_foreign_helper' show JS, JS_EMBEDDED_GLOBAL, JS_GET_NAME;

import 'dart:_js_helper' show JsCache, NoInline;

import 'dart:_interceptors' show JSArray;

/// No-op method that is called to inform the compiler that unmangled named
/// must be preserved.
preserveNames() {}

/// A map from mangled names to "reflective" names, that is, unmangled names
/// with some additional information, such as, number of required arguments.
/// This map is for mangled names used as instance members.
final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap(
    JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES));

/// A map from "reflective" names to mangled names (the reverse of
/// [mangledNames]).
final _LazyReflectiveNamesMap reflectiveNames = new _LazyReflectiveNamesMap(
    JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES), true);

/// A map from mangled names to "reflective" names (see [mangledNames]).  This
/// map is for globals, that is, static and top-level members.
final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap(
    JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES));

/// A map from "reflective" names to mangled names (the reverse of
/// [mangledGlobalNames]).
final _LazyReflectiveNamesMap reflectiveGlobalNames =
    new _LazyReflectiveNamesMap(
        JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false);

/// Implements a mapping from mangled names to their reflective counterparts.
/// The propertiy names of [_jsMangledNames] are the mangled names, and the
/// values are the "reflective" names.
class _LazyMangledNamesMap {
  /// [_jsMangledNames] is a JavaScript object literal.
  var _jsMangledNames;

  _LazyMangledNamesMap(this._jsMangledNames);

  String operator [](String key) {
    var result = JS('var', '#[#]', _jsMangledNames, key);
    // Filter out all non-string values to protect against polution from
    // ancillary fields in [_jsMangledNames].
    bool filter = JS('bool', 'typeof # !== "string"', result);
    // To ensure that the inferrer sees that result is a String, we explicitly
    // give it a better type here.
    return filter ? null : JS('String', '#', result);
  }
}

/// Extends [_LazyMangledNamesMap] with additional support for adding mappings
/// from mangled setter names to their reflective counterpart by rewriting a
/// corresponding entry for a getter name, if it exists.
class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap {
  _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames);

  String operator [](String key) {
    String result = super[key];
    String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
    if (result == null && key.startsWith(setterPrefix)) {
      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
      int setterPrefixLength = setterPrefix.length;

      // Generate the setter name from the getter name.
      key = '$getterPrefix${key.substring(setterPrefixLength)}';
      result = super[key];
      return (result != null) ? "${result}=" : null;
    }
    return result;
  }
}

/// Implements the inverse of [_LazyMangledNamesMap]. As it would be too
/// expensive to seach the mangled names map for a value that corresponds to
/// the lookup key on each invocation, we compute the full mapping in demand
/// and cache it. The cache is invalidated when the underlying [_jsMangledNames]
/// object changes its length. This condition is sufficient as the name mapping
/// can only grow over time.
/// When [_isInstance] is true, we also apply the inverse of the setter/getter
/// name conversion implemented by [_LazyMangledInstanceNamesMap].
class _LazyReflectiveNamesMap {
  /// [_jsMangledNames] is a JavaScript object literal.
  final _jsMangledNames;
  final bool _isInstance;
  int _cacheLength = 0;
  Map<String, String> _cache;

  _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance);

  Map<String, String> _updateReflectiveNames() {
    preserveNames();
    Map<String, String> result = <String, String>{};
    List keys = JS('List', 'Object.keys(#)', _jsMangledNames);
    for (String key in keys) {
      var reflectiveName = JS('var', '#[#]', _jsMangledNames, key);
      // Filter out all non-string values to protect against polution from
      // ancillary fields in [_jsMangledNames].
      bool filter = JS('bool', 'typeof # !== "string"', reflectiveName);
      if (filter) continue;
      result[reflectiveName] = JS('String', '#', key);

      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
      if (_isInstance && key.startsWith(getterPrefix)) {
        int getterPrefixLength = getterPrefix.length;
        String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
        result['$reflectiveName='] =
            '$setterPrefix${key.substring(getterPrefixLength)}';
      }
    }
    return result;
  }

  int get _jsMangledNamesLength =>
      JS('int', 'Object.keys(#).length', _jsMangledNames);

  String operator [](String key) {
    if (_cache == null || _jsMangledNamesLength != _cacheLength) {
      _cache = _updateReflectiveNames();
      _cacheLength = _jsMangledNamesLength;
    }
    return _cache[key];
  }
}

@pragma('dart2js:noInline')
List extractKeys(victim) {
  var result = JS('', '# ? Object.keys(#) : []', victim, victim);
  return new JSArray.markFixed(result);
}

/// Returns the (global) unmangled version of [name].
///
/// Normally, you should use [mangledGlobalNames] directly, but this method
/// doesn't tell the compiler to preserve names. So this method only returns a
/// non-null value if some other component has made the compiler preserve names.
///
/// This is used, for example, to return unmangled names from TypeImpl.toString
/// *if* names are being preserved for other reasons (use of dart:mirrors, for
/// example).
String unmangleGlobalNameIfPreservedAnyways(String name) {
  var names = JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES);
  return JsCache.fetch(names, name);
}

String unmangleAllIdentifiersIfPreservedAnyways(String str) {
  return JS(
      'String',
      r'''
        (function(str, names) {
          return str.replace(
              /[^<,> ]+/g,
              function(m) { return names[m] || m; });
        })(#, #)''',
      str,
      JS_EMBEDDED_GLOBAL('', MANGLED_GLOBAL_NAMES));
}
