// Copyright (c) 2015, 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 library defines the operations that define and manipulate Dart
/// classes.  Included in this are:
///   - Generics
///   - Class metadata
///   - Extension methods
///

// TODO(leafp): Consider splitting some of this out.
part of dart._runtime;

///
/// Returns a new type that mixes members from base and all mixins.
///
/// Each mixin applies in sequence, with further to the right ones overriding
/// previous entries.
///
/// For each mixin, we only take its own properties, not anything from its
/// superclass (prototype).
///
mixin(base, @rest mixins) => JS(
    '',
    '''(() => {
  // Create an initializer for the mixin, so when derived constructor calls
  // super, we can correctly initialize base and mixins.

  // Create a class that will hold all of the mixin methods.
  class Mixin extends $base {}
  // Copy each mixin's methods, with later ones overwriting earlier entries.
  for (let m of $mixins) {
    $copyProperties(Mixin.prototype, m.prototype);
  }
  // Initializer method: run mixin initializers, then the base.
  Mixin.prototype.new = function(...args) {
    // Run mixin initializers. They cannot have arguments.
    // Run them backwards so most-derived mixin is initialized first.
    for (let i = $mixins.length - 1; i >= 0; i--) {
      $mixins[i].prototype.new.call(this);
    }
    // Run base initializer.
    $base.prototype.new.apply(this, args);
  };

  // Set the signature of the Mixin class to be the composition
  // of the signatures of the mixins.
  $setSignature(Mixin, {
    methods: () => {
      let s = {};
      for (let m of $mixins) {
        $copyProperties(s, m[$_methodSig]);
      }
      return s;
    },
    fields: () => {
      let s = {};
      for (let m of $mixins) {
        $copyProperties(s, m[$_fieldSig]);
      }
      return s;
    },
    getters: () => {
      let s = {};
      for (let m of $mixins) {
        $copyProperties(s, m[$_getterSig]);
      }
      return s;
    },
    setters: () => {
      let s = {};
      for (let m of $mixins) {
        $copyProperties(s, m[$_setterSig]);
      }
      return s;
    }
  });

  // Save mixins for reflection
  Mixin[$_mixins] = $mixins;
  return Mixin;
})()''');

/// The Symbol for storing type arguments on a specialized generic type.
final _mixins = JS('', 'Symbol("mixins")');

getMixins(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
    clazz, _mixins, clazz, _mixins);

@JSExportName('implements')
final _implements = JS('', 'Symbol("implements")');

getImplements(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
    clazz, _implements, clazz, _implements);

/// The Symbol for storing type arguments on a specialized generic type.
final _typeArguments = JS('', 'Symbol("typeArguments")');

final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');

/// Wrap a generic class builder function with future flattening.
flattenFutures(builder) => JS(
    '',
    '''(() => {
  function flatten(T) {
    if (!T) return $builder($dynamic);
    let futureClass = $getGenericClass($Future);
    //TODO(leafp): This only handles the direct flattening case.
    // It would probably be good to at least search up the class
    // hierarchy.  If we keep doing flattening long term, we may
    // want to implement the full future flattening per spec.
    if ($getGenericClass(T) == futureClass) {
      let args = $getGenericArgs(T);
      if (args) return $builder(args[0]);
    }
    return $builder(T);
  }
  return flatten;
})()''');

/// Memoize a generic type constructor function.
generic(typeConstructor, [setBaseClass]) => JS(
    '',
    '''(() => {
  let length = $typeConstructor.length;
  if (length < 1) {
    $throwInternalError('must have at least one generic type argument');
  }
  let resultMap = new Map();
  function makeGenericType(...args) {
    if (args.length != length && args.length != 0) {
      $throwInternalError('requires ' + length + ' or 0 type arguments');
    }
    while (args.length < length) args.push($dynamic);

    let value = resultMap;
    for (let i = 0; i < length; i++) {
      let arg = args[i];
      if (arg == null) {
        $throwInternalError('type arguments should not be null: '
                          + $typeConstructor);
      }
      let map = value;
      value = map.get(arg);
      if (value === void 0) {
        if (i + 1 == length) {
          value = $typeConstructor.apply(null, args);
          // Save the type constructor and arguments for reflection.
          if (value) {
            value[$_typeArguments] = args;
            value[$_originalDeclaration] = makeGenericType;
          }
          map.set(arg, value);
          if ($setBaseClass) $setBaseClass(value);
        } else {
          value = new Map();
          map.set(arg, value);
        }
      }
    }
    return value;
  }
  makeGenericType[$_genericTypeCtor] = $typeConstructor;
  return makeGenericType;
})()''');

getGenericClass(type) =>
    JS('', '$safeGetOwnProperty($type, $_originalDeclaration)');

getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)');

// TODO(vsm): Collapse into one expando.
final _constructorSig = JS('', 'Symbol("sigCtor")');
final _methodSig = JS('', 'Symbol("sigMethod")');
final _fieldSig = JS('', 'Symbol("sigField")');
final _getterSig = JS('', 'Symbol("sigGetter")');
final _setterSig = JS('', 'Symbol("sigSetter")');
final _staticSig = JS('', 'Symbol("sigStaticMethod")');
final _staticFieldSig = JS('', 'Symbol("sigStaticField")');
final _staticGetterSig = JS('', 'Symbol("sigStaticGetter")');
final _staticSetterSig = JS('', 'Symbol("sigStaticSetter")');
final _genericTypeCtor = JS('', 'Symbol("genericType")');

// TODO(vsm): Collapse this as well - just provide a dart map to mirrors code.
// These are queried by mirrors code.
getConstructorSig(value) => JS('', '#[#]', value, _constructorSig);
getMethodSig(value) => JS('', '#[#]', value, _methodSig);
getFieldSig(value) => JS('', '#[#]', value, _fieldSig);
getGetterSig(value) => JS('', '#[#]', value, _getterSig);
getSetterSig(value) => JS('', '#[#]', value, _setterSig);
getStaticSig(value) => JS('', '#[#]', value, _staticSig);
getStaticFieldSig(value) => JS('', '#[#]', value, _staticFieldSig);
getStaticGetterSig(value) => JS('', '#[#]', value, _staticGetterSig);
getStaticSetterSig(value) => JS('', '#[#]', value, _staticSetterSig);

getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);

/// Get the type of a method from an object using the stored signature
getType(obj) => JS(
    '',
    '''(() => {
  return $obj == null ? $Object : $obj.__proto__.constructor;
})()''');

bool isJsInterop(obj) {
  if (JS('bool', 'typeof # === "function"', obj)) {
    // A function is a Dart function if it has runtime type information.
    return _getRuntimeType(obj) == null;
  }
  // Primitive types are not JS interop types.
  if (JS('bool', 'typeof # !== "object"', obj)) return false;

  // Extension types are not considered JS interop types.
  // Note that it is still possible to call typed JS interop methods on
  // extension types but the calls must be statically typed.
  if (getExtensionType(obj) != null) return false;
  return JS('bool', '!($obj instanceof $Object)');
}

/// Get the type of a method from a type using the stored signature
getMethodType(type, name) => JS(
    '',
    '''(() => {
  let sigObj = $type[$_methodSig];
  if (sigObj === void 0) return void 0;
  return sigObj[$name];
})()''');

getFieldType(type, name) => JS(
    '',
    '''(() => {
  let sigObj = $type[$_fieldSig];
  if (sigObj === void 0) return void 0;
  let fieldType = sigObj[$name];
  // workaround to handle metadata.
  return (fieldType instanceof Array) ? fieldType[0] : fieldType;
})()''');

getSetterType(type, name) => JS(
    '',
    '''(() => {
  let sigObj = $type[$_setterSig];
  if (sigObj === void 0) return void 0;
  return sigObj[$name];
})()''');

/// Get the type of a constructor from a class using the stored signature
/// If name is undefined, returns the type of the default constructor
/// Returns undefined if the constructor is not found.
classGetConstructorType(cls, name) => JS(
    '',
    '''(() => {
  if(!$name) $name = 'new';
  if ($cls === void 0) return void 0;
  if ($cls == null) return void 0;
  let sigCtor = $cls[$_constructorSig];
  if (sigCtor === void 0) return void 0;
  return sigCtor[$name];
})()''');

/// Given an object and a method name, tear off the method.
/// Sets the runtime type of the torn off method appropriately,
/// and also binds the object.
///
/// If the optional `f` argument is passed in, it will be used as the method.
/// This supports cases like `super.foo` where we need to tear off the method
/// from the superclass, not from the `obj` directly.
/// TODO(leafp): Consider caching the tearoff on the object?
bind(obj, name, f) => JS(
    '',
    '''(() => {
  if ($f === void 0) $f = $obj[$name];
  $f = $f.bind($obj);
  // TODO(jmesserly): track the function's signature on the function, instead
  // of having to go back to the class?
  let sig = $getMethodType($getType($obj), $name);
  $assert_(sig);
  $tag($f, sig);
  return $f;
})()''');

/// Instantiate a generic method.
///
/// We need to apply the type arguments both to the function, as well as its
/// associated function type.
gbind(f, @rest typeArgs) {
  var result = JS('', '#.apply(null, #)', f, typeArgs);
  var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs);
  tag(result, sig);
  return result;
}

// Set up the method signature field on the constructor
_setInstanceSignature(f, sigF, kind) => JS(
    '',
    '''(() => {
  $defineMemoizedGetter($f, $kind, () => {
    let sigObj = $sigF();
    let proto = $f.__proto__;
    // We need to set the root proto to null not undefined.
    sigObj.__proto__ = ($kind in proto) ? proto[$kind] : null;
    return sigObj;
  });
})()''');

_setMethodSignature(f, sigF) => _setInstanceSignature(f, sigF, _methodSig);
_setFieldSignature(f, sigF) => _setInstanceSignature(f, sigF, _fieldSig);
_setGetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _getterSig);
_setSetterSignature(f, sigF) => _setInstanceSignature(f, sigF, _setterSig);

// Set up the constructor signature field on the constructor
_setConstructorSignature(f, sigF) =>
    JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)');

// Set up the static signature field on the constructor
_setStaticSignature(f, sigF) =>
    JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)');

_setStaticFieldSignature(f, sigF) =>
    JS('', '$defineMemoizedGetter($f, $_staticFieldSig, $sigF)');

_setStaticGetterSignature(f, sigF) =>
    JS('', '$defineMemoizedGetter($f, $_staticGetterSig, $sigF)');

_setStaticSetterSignature(f, sigF) =>
    JS('', '$defineMemoizedGetter($f, $_staticSetterSig, $sigF)');

// Set the lazily computed runtime type field on static methods
_setStaticTypes(f, names) => JS(
    '',
    '''(() => {
  for (let name of $names) {
    // TODO(vsm): Need to generate static methods.
    if (!$f[name]) continue;
    $tagLazy($f[name], function() {
      return $f[$_staticSig][name];
    })
  }
})()''');

/// Set up the type signature of a class (constructor object)
/// f is a constructor object
/// signature is an object containing optional properties as follows:
///  methods: A function returning an object mapping method names
///   to method types.  The function is evaluated lazily and cached.
///  statics: A function returning an object mapping static method
///   names to types.  The function is evalutated lazily and cached.
///  names: An array of the names of the static methods.  Used to
///   permit eagerly setting the runtimeType field on the methods
///   while still lazily computing the type descriptor object.
///  fields: A function returning an object mapping instance field
///    names to types.
setSignature(f, signature) => JS(
    '',
    '''(() => {
  // TODO(ochafik): Deconstruct these when supported by Chrome.
  let constructors =
    ('constructors' in signature) ? signature.constructors : () => ({});
  let methods =
    ('methods' in signature) ? signature.methods : () => ({});
  let fields =
    ('fields' in signature) ? signature.fields : () => ({});
  let getters =
    ('getters' in signature) ? signature.getters : () => ({});
  let setters =
    ('setters' in signature) ? signature.setters : () => ({});
  let statics =
    ('statics' in signature) ? signature.statics : () => ({});
  let staticFields =
    ('sfields' in signature) ? signature.sfields : () => ({});
  let staticGetters =
    ('sgetters' in signature) ? signature.sgetters : () => ({});
  let staticSetters =
    ('ssetters' in signature) ? signature.ssetters : () => ({});
  let names =
    ('names' in signature) ? signature.names : [];
  $_setConstructorSignature($f, constructors);
  $_setMethodSignature($f, methods);
  $_setFieldSignature($f, fields);
  $_setGetterSignature($f, getters);
  $_setSetterSignature($f, setters);
  $_setStaticSignature($f, statics);
  $_setStaticFieldSignature($f, staticFields);
  $_setStaticGetterSignature($f, staticGetters);
  $_setStaticSetterSignature($f, staticSetters);
  $_setStaticTypes($f, names);
})()''');

_hasSigEntry(type, sigF, name) => JS(
    '',
    '''(() => {
  let sigObj = $type[$sigF];
  if (sigObj === void 0) return false;
  return $name in sigObj;
})()''');

hasMethod(type, name) => _hasSigEntry(type, _methodSig, name);
hasGetter(type, name) => _hasSigEntry(type, _getterSig, name);
hasSetter(type, name) => _hasSigEntry(type, _setterSig, name);
hasField(type, name) => _hasSigEntry(type, _fieldSig, name);

/// Given a class and an initializer method name, creates a constructor
/// function with the same name.
///
/// After we define the named constructor, the class can be constructed with
/// `new SomeClass.name(args)`.
defineNamedConstructor(clazz, name) => JS(
    '',
    '''(() => {
  let proto = $clazz.prototype;
  let initMethod = proto[$name];
  let ctor = function(...args) { initMethod.apply(this, args); };
  ctor[$isNamedConstructor] = true;
  ctor.prototype = proto;
  // Use defineProperty so we don't hit a property defined on Function,
  // like `caller` and `arguments`.
  $defineProperty($clazz, $name, { value: ctor, configurable: true });
})()''');

final _extensionType = JS('', 'Symbol("extensionType")');

getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);

final dartx = JS('', 'dartx');

getExtensionSymbol(name) {
  var sym = JS('', 'dartx[#]', name);
  if (sym == null) {
    sym = JS('', 'Symbol("dartx." + #.toString())', name);
    JS('', 'dartx[#] = #', name, sym);
  }
  return sym;
}

defineExtensionNames(names) =>
    JS('', '#.forEach(#)', names, getExtensionSymbol);

/// Install properties in prototype-first order.  Properties / descriptors from
/// more specific types should overwrite ones from less specific types.
void _installProperties(jsProto, extProto) {
  // This relies on the Dart type literal evaluating to the JavaScript
  // constructor.
  var coreObjProto = JS('', '#.prototype', Object);

  var parentsExtension = JS('', '(#.__proto__)[#]', jsProto, _extensionType);
  var installedParent =
      JS('', '# && #.prototype', parentsExtension, parentsExtension);

  _installProperties2(jsProto, extProto, coreObjProto, installedParent);
}

void _installProperties2(jsProto, extProto, coreObjProto, installedParent) {
  if (JS('bool', '# === #', extProto, coreObjProto)) {
    _installPropertiesForObject(jsProto, coreObjProto);
    return;
  }
  if (JS('bool', '# !== #', jsProto, extProto)) {
    var extParent = JS('', '#.__proto__', extProto);

    // If the extension methods of the parent have been installed on the parent
    // of [jsProto], the methods will be available via prototype inheritance.

    if (JS('bool', '# !== #', installedParent, extParent)) {
      _installProperties2(jsProto, extParent, coreObjProto, installedParent);
    }
  }
  copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto));
}

void _installPropertiesForObject(jsProto, coreObjProto) {
  // core.Object members need to be copied from the non-symbol name to the
  // symbol name.
  var names = getOwnPropertyNames(coreObjProto);
  for (int i = 0; i < JS('int', '#.length', names); ++i) {
    var name = JS('', '#[#]', names, i);
    var desc = getOwnPropertyDescriptor(coreObjProto, name);
    defineProperty(jsProto, getExtensionSymbol(name), desc);
  }
  return;
}

/// Copy symbols from the prototype of the source to destination.
/// These are the only properties safe to copy onto an existing public
/// JavaScript class.
registerExtension(jsType, dartExtType) => JS(
    '',
    '''(() => {
  // TODO(vsm): Not all registered js types are real.
  if (!jsType) return;

  let extProto = $dartExtType.prototype;
  let jsProto = $jsType.prototype;

  // TODO(vsm): This sometimes doesn't exist on FF.  These types will be
  // broken.
  if (!jsProto) return;

  // Mark the JS type's instances so we can easily check for extensions.
  jsProto[$_extensionType] = $dartExtType;
  $_installProperties(jsProto, extProto);
  function updateSig(sigF) {
    let originalSigFn = $getOwnPropertyDescriptor($dartExtType, sigF).get;
    $assert_(originalSigFn);
    $defineMemoizedGetter($jsType, sigF, originalSigFn);
  }
  updateSig($_methodSig);
  updateSig($_fieldSig);
  updateSig($_getterSig);
  updateSig($_setterSig);
})()''');

///
/// Mark a concrete type as implementing extension methods.
/// For example: `class MyIter implements Iterable`.
///
/// This takes a list of names, which are the extension methods implemented.
/// It will add a forwarder, so the extension method name redirects to the
/// normal Dart method name. For example:
///
///     defineExtensionMembers(MyType, ['add', 'remove']);
///
/// Results in:
///
///     MyType.prototype[dartx.add] = MyType.prototype.add;
///     MyType.prototype[dartx.remove] = MyType.prototype.remove;
///
// TODO(jmesserly): essentially this gives two names to the same method.
// This benefit is roughly equivalent call performance either way, but the
// cost is we need to call defineExtensionMembers any time a subclass
// overrides one of these methods.
defineExtensionMembers(type, methodNames) => JS(
    '',
    '''(() => {
  let proto = $type.prototype;
  for (let name of $methodNames) {
    let method = $getOwnPropertyDescriptor(proto, name);
    $defineProperty(proto, $getExtensionSymbol(name), method);
  }
  // Ensure the signature is available too.
  // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially
  // we need to copy the signature (and in the future, other data like
  // annotations) any time we copy a method as part of our metaprogramming.
  // It might be more friendly to JS metaprogramming if we include this info
  // on the function.

  function upgradeSig(sigF) {
    let originalSigFn = $getOwnPropertyDescriptor($type, sigF).get;
    $defineMemoizedGetter(type, sigF, function() {
      let sig = originalSigFn();
      let propertyNames = Object.getOwnPropertyNames(sig);
      for (let name of methodNames) {
        if (name in sig) {
          sig[$getExtensionSymbol(name)] = sig[name];
        }
      }
      return sig;
    });
  };
  upgradeSig($_methodSig);
  upgradeSig($_fieldSig);
  upgradeSig($_getterSig);
  upgradeSig($_setterSig);
})()''');

/// Sets the type of `obj` to be `type`
setType(obj, type) {
  JS('', '#.__proto__ = #.prototype', obj, type);
  return obj;
}

/// Sets the element type of a list literal.
list(obj, elementType) =>
    JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))');

/// Link the extension to the type it's extending as a base class.
setBaseClass(derived, base) {
  JS('', '#.prototype.__proto__ = #.prototype', derived, base);
  // We use __proto__ to track the superclass hierarchy (see isSubtype).
  JS('', '#.__proto__ = #', derived, base);
}

/// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>`
setExtensionBaseClass(derived, base) {
  // Mark the generic type as an extension type and link the prototype objects
  return JS(
      '',
      '''(() => {
    if ($base) {
      $derived.prototype[$_extensionType] = $derived;
      $derived.prototype.__proto__ = $base.prototype
    }
})()''');
}

/// Given a special constructor function that creates a function instances,
/// and a class with a `call` method, merge them so the constructor function
/// will have the correct methods and prototype.
///
/// For example:
///
///     lib.Foo = dart.callableClass(
///         function Foo { function call(...args) { ... } ... return call; },
///         class Foo { call(x) { ... } });
///     ...
///       let f = new lib.Foo();
///       f(42);
callableClass(callableCtor, classExpr) {
  JS('', '#.prototype = #.prototype', callableCtor, classExpr);
  // We're not going to use the original class, so we can safely replace it to
  // point at this constructor for the runtime type information.
  JS('', '#.prototype.constructor = #', callableCtor, callableCtor);
  JS('', '#.__proto__ = #', callableCtor, classExpr);
  return callableCtor;
}

/// Given a class and an initializer method name and a call method, creates a
/// constructor function with the same name.
///
/// For example it can be called with `new SomeClass.name(args)`.
///
/// The constructor
defineNamedConstructorCallable(clazz, name, ctor) => JS(
    '',
    '''(() => {
  ctor.prototype = $clazz.prototype;
  // Use defineProperty so we don't hit a property defined on Function,
  // like `caller` and `arguments`.
  $defineProperty($clazz, $name, { value: ctor, configurable: true });
})()''');

defineEnumValues(enumClass, names) => JS(
    '',
    '''(() => {
  let values = [];
  for (var i = 0; i < $names.length; i++) {
    let value = $const_(new $enumClass(i));
    values.push(value);
    Object.defineProperty($enumClass, $names[i],
        { value: value, configurable: true });
  }
  $enumClass.values = $constList(values, $enumClass);
})()''');
