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

library dart._js_mirrors;

import 'dart:mirrors';
import 'dart:_foreign_helper' show JS;
import 'dart:_internal' as _internal;

String getName(Symbol symbol) =>
    _internal.Symbol.getName(symbol as _internal.Symbol);

Symbol getSymbol(name, library) =>
    throw new UnimplementedError("MirrorSystem.getSymbol unimplemented");

final currentJsMirrorSystem = throw new UnimplementedError(
    "MirrorSystem.currentJsMirrorSystem unimplemented");

final _typeMirror = JS('', 'Symbol("_typeMirror")');

InstanceMirror reflect(reflectee) {
  // TODO(vsm): Consider caching the mirror here.  Unlike the type below,
  // reflectee may be a primitive - i.e., we can't just add an expando.
  if (reflectee is Function) {
    return new JsClosureMirror._(reflectee);
  } else {
    return new JsInstanceMirror._(reflectee);
  }
}

TypeMirror reflectType(Type key) {
  var unwrapped = _unwrap(key);
  var property = JS('', 'Object.getOwnPropertyDescriptor(#, #)', unwrapped, _typeMirror);
  if (property != null) {
    return JS('', '#.value', property);
  }
  // TODO(vsm): Might not be a class.
  var mirror = new JsClassMirror._(key);
  JS('', '#[#] = #', unwrapped, _typeMirror, mirror);
  return mirror;
}

final dynamic _dart = JS('', 'dart');

dynamic _dload(obj, String name) {
  return JS('', '#.dload(#, #)', _dart, obj, name);
}

void _dput(obj, String name, val) {
  JS('', '#.dput(#, #, #)', _dart, obj, name, val);
}

dynamic _dcall(obj, List args) {
  return JS('', '#.dcall(#, ...#)', _dart, obj, args);
}

dynamic _dsend(obj, String name, List args) {
  return JS('', '#.dsend(#, #, ...#)', _dart, obj, name, args);
}

dynamic _getGenericClass(obj) {
  return JS('', '#.getGenericClass(#)', _dart, obj);
}

dynamic _getGenericArgs(obj) {
  return JS('', '#.getGenericArgs(#)', _dart, obj);
}

dynamic _defaultConstructorType(type) {
  return JS('', '#.definiteFunctionType(#, [])', _dart, type);
}

dynamic _getMixins(type) {
  return JS('', '#.getMixins(#, [])', _dart, type);
}

typedef T _Lazy<T>();

dynamic _getESSymbol(Symbol symbol) =>
    _internal.Symbol.getNativeSymbol(symbol as _internal.Symbol);

dynamic _getMember(Symbol symbol) {
  var privateSymbol = _getESSymbol(symbol);
  if (privateSymbol != null) {
    return privateSymbol;
  }
  return getName(symbol);
}

String _getNameForESSymbol(member) {
  // Convert private JS symbol "Symbol(_foo)" to string "_foo".
  assert(JS('bool', 'typeof # == "symbol"', member));
  var str = member.toString();
  assert(str.startsWith('Symbol(') && str.endsWith(')'));
  return str.substring(7, str.length - 1);
}

Symbol _getSymbolForESSymbol(member) {
  var name = _getNameForESSymbol(member);
  return new _internal.Symbol.es6(name, member);
}

// The [member] must be either a string (public) or an ES6 symbol (private).
Symbol _getSymbolForMember(member) {
  if (member is String) {
    return new Symbol(member);
  } else {
    var name = _getNameForESSymbol(member);
    return new _internal.Symbol.es6(name, member);
  }
}

Map<Symbol, dynamic> _toDartMap(data) {
  if (data == null) return {};
  var map = new Map<Symbol, dynamic>();
  // Note: we recorded a map from fields/methods to their type and metadata.
  // The key is a string name for public members but an ES6 symbol for private
  // ones.  That's works nicely for dynamic operations, but dart:mirrors expects
  // Dart symbols, so we convert here.
  var publicMembers = JS('', 'Object.getOwnPropertyNames(#)', data);
  for (var member in publicMembers) {
    var symbol = new Symbol(member);
    map[symbol] = JS('', '#[#]', data, member);
  }

  var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data);
  for (var member in privateMembers) {
    var symbol = _getSymbolForESSymbol(member);
    map[symbol] = JS('', '#[#]', data, member);
  }
  return map;
}

Map<Symbol, dynamic> _getConstructors(obj) {
  List sig = JS('', '#.getConstructorSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getFields(obj) {
  List sig = JS('', '#.getFieldSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getMethods(obj) {
  List sig = JS('', '#.getMethodSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getGetters(obj) {
  List sig = JS('', '#.getGetterSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getSetters(obj) {
  List sig = JS('', '#.getSetterSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getStaticFields(obj) {
  List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getStatics(obj) {
  List sig = JS('', '#.getStaticSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getStaticGetters(obj) {
  List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj);
  return _toDartMap(sig);
}

Map<Symbol, dynamic> _getStaticSetters(obj) {
  List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj);
  return _toDartMap(sig);
}

// TODO(vsm): These methods need to validate whether we really have a
// WrappedType or a raw type that should be wrapped (as opposed to a
// function).
dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj);

dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj);

dynamic _runtimeType(obj) =>
  _wrap(JS('', '#.getReifiedType(#)', _dart, obj));

_unimplemented(Type t, Invocation i) {
  throw new UnimplementedError('$t.${getName(i.memberName)} unimplemented');
}

dynamic _toJsMap(Map<Symbol, dynamic> map) {
  var obj = JS('', '{}');
  map.forEach((Symbol key, value) {
    JS('', '#[#] = #', obj, getName(key), value);
  });
  return obj;
}

class JsMirror implements Mirror {
  noSuchMethod(Invocation i) {
    _unimplemented(this.runtimeType, i);
  }
}

class JsCombinatorMirror extends JsMirror implements CombinatorMirror {
}

class JsDeclarationMirror extends JsMirror implements DeclarationMirror {
}

class JsIsolateMirror extends JsMirror implements IsolateMirror {
}

class JsLibraryDependencyMirror extends JsMirror implements LibraryDependencyMirror {
}

class JsObjectMirror extends JsMirror implements ObjectMirror {
}

class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {

  // Reflected object
  final reflectee;
  bool get hasReflectee => true;

  ClassMirror get type {
    // The spec guarantees that `null` is the singleton instance of the `Null`
    // class.
    if (reflectee == null) return reflectClass(Null);
    return reflectType(_runtimeType(reflectee));
  }

  JsInstanceMirror._(this.reflectee);

  bool operator==(Object other) {
    return (other is JsInstanceMirror) && identical(reflectee, other.reflectee);
  }

  int get hashCode {
    // Avoid hash collisions with the reflectee. This constant is in Smi range
    // and happens to be the inner padding from RFC 2104.
    return identityHashCode(reflectee) ^ 0x36363636;
  }

  // Returns a String for public members or an ES6 symbol for private members.
  _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args,
      Map<Symbol, dynamic> namedArgs]) {
    return _getMember(symbol);
  }

  InstanceMirror getField(Symbol symbol) {
    var name = _getAccessor(reflectee, symbol);
    var field = _dload(reflectee, name);
    return reflect(field);
  }

  InstanceMirror setField(Symbol symbol, Object value) {
    var name = _getAccessor(reflectee, symbol);
    _dput(reflectee, name, value);
    return reflect(value);
  }

  InstanceMirror invoke(Symbol symbol, List<dynamic> args,
      [Map<Symbol, dynamic> namedArgs]) {
    var name = _getAccessor(reflectee, symbol, args, namedArgs);
    if (namedArgs != null) {
      args = new List.from(args);
      args.add(_toJsMap(namedArgs));
    }
    var result = _dsend(reflectee, name, args);
    return reflect(result);
  }

  String toString() => "InstanceMirror on '$reflectee'";
}

class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
  JsClosureMirror._(reflectee) : super._(reflectee);

  InstanceMirror apply(List<dynamic> args,
      [Map<Symbol, dynamic> namedArgs]) {
    if (namedArgs != null) {
      args = new List.from(args);
      args.add(_toJsMap(namedArgs));
    }
    var result = _dcall(reflectee, args);
    return reflect(result);
  }
}

class JsClassMirror extends JsMirror implements ClassMirror {
  final Type _cls;
  final Symbol simpleName;
  // Generic class factory
  final dynamic _raw;

  // TODO(vsm): Do this properly
  ClassMirror _mixin = null;
  List<TypeMirror> _typeArguments;

  List<InstanceMirror> _metadata;
  Map<Symbol, DeclarationMirror> _declarations;

  List<InstanceMirror> get metadata {
    if (_metadata == null) {
      // Load metadata.
      var unwrapped = _unwrap(_cls);
      // Only get metadata directly embedded on this class, not its
      // superclasses.
      var fn = JS('Function',
        'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
        unwrapped, unwrapped);
      _metadata = (fn == null)
          ? const <InstanceMirror>[]
          : new List<InstanceMirror>.unmodifiable(
              fn().map((i) => reflect(i)));
    }
    return _metadata;
  }

  Map<Symbol, DeclarationMirror> get declarations {
    if (_declarations == null) {
      // Load declarations.
      // TODO(vsm): This is only populating the default constructor right now.
      _declarations = new Map<Symbol, DeclarationMirror>();
      var unwrapped = _unwrap(_cls);
      var constructors = _getConstructors(unwrapped);
      constructors.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft);
      });
      if (constructors.isEmpty) {
        // Add a default
        var name = 'new';
        var ft = _defaultConstructorType(_unwrap(_cls));
        var symbol = new Symbol(name);
        _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft);
      }
      var fields = _getFields(unwrapped);
      fields.forEach((symbol, t) {
        var metadata = [];
        if (t is List) {
          metadata = t.skip(1).toList();
          t = t[0];
        }
        _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadata);
      });
      var methods = _getMethods(unwrapped);
      methods.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
      });
      var getters = _getGetters(unwrapped);
      getters.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
      });
      var setters = _getSetters(unwrapped);
      setters.forEach((symbol, ft) {
        var name = getName(symbol) + '=';
        // Create a separate symbol for the setter.
        symbol = new _internal.Symbol.es6(name, _getESSymbol(symbol));
        _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol, ft);
      });
      var staticFields = _getStaticFields(unwrapped);
      staticFields.forEach((symbol, t) {
        var name = getName(symbol);
        var metadata = [];
        if (t is List) {
          metadata = t.skip(1).toList();
          t = t[0];
        }
        _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadata);
      });
      var statics = _getStatics(unwrapped);
      statics.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
      });
      var staticGetters = _getStaticGetters(unwrapped);
      staticGetters.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
      });
      var staticSetters = _getStaticSetters(unwrapped);
      staticSetters.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, ft);
      });
      _declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
    }
    return _declarations;
  }

  JsClassMirror._(Type cls)
      : _cls = cls,
        _raw = _getGenericClass(_unwrap(cls)),
        simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) {
    var typeArgs = _getGenericArgs(_unwrap(cls));
    if (typeArgs == null) {
      _typeArguments = const[];
    } else {
      _typeArguments = new List.unmodifiable(typeArgs.map((t) => reflectType(_wrap(t))));
    }
  }

  InstanceMirror newInstance(Symbol constructorName, List args,
      [Map<Symbol, dynamic> namedArgs]) {
    // TODO(vsm): Support factory constructors and named arguments.
    var name = getName(constructorName);
    assert(namedArgs == null || namedArgs.isEmpty);
    var instance = (name == 'new' || name == '')
      ? JS('', 'new #(...#)', _unwrap(_cls), args)
      : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args);
    return reflect(instance);
  }

  // TODO(vsm): Need to check for NSM, types on accessors below.  Unlike the
  // InstanceMirror case, there is no dynamic helper to delegate to - we never
  // need a dload, etc. on a static.

  InstanceMirror getField(Symbol symbol) {
    var name = getName(symbol);
    return reflect(JS('', '#[#]', _unwrap(_cls), name));
  }

  InstanceMirror setField(Symbol symbol, Object value) {
    var name = getName(symbol);
    JS('', '#[#] = #', _unwrap(_cls), name, value);
    return reflect(value);
  }

  InstanceMirror invoke(Symbol symbol, List<dynamic> args,
      [Map<Symbol, dynamic> namedArgs]) {
    var name = getName(symbol);
    if (namedArgs != null) {
      args = new List.from(args);
      args.add(_toJsMap(namedArgs));
    }
    var result = JS('', '#.#(...#)', _unwrap(_cls), name, args);
    return reflect(result);
  }

  List<ClassMirror> get superinterfaces {
    _Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls));
    if (interfaceThunk == null) {
      return [];
    } else {
      List<Type> interfaces = interfaceThunk();
      return interfaces.map((t) => reflectType(t)).toList();
    }
  }

  bool get hasReflectedType => true;
  Type get reflectedType { return _cls; }

  bool get isOriginalDeclaration => _raw == null;

  List<TypeMirror> get typeArguments => _typeArguments;

  TypeMirror get originalDeclaration {
    // TODO(vsm): Handle generic case.  How should we represent an original
    // declaration for a generic class?
    if (_raw == null) {
      return this;
    }
    throw new UnimplementedError("ClassMirror.originalDeclaration unimplemented");
  }

  ClassMirror get superclass {
    if (_cls == Object) {
      return null;
    } else {
      return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls))));
    }
  }

  ClassMirror get mixin {
    if (_mixin != null) {
      return _mixin;
    }
    var mixins = _getMixins(_unwrap(_cls));
    if (mixins == null || mixins.isEmpty) {
      // If there is no mixin, return this mirror per API.
      _mixin = this;
      return _mixin;
    }
    if (mixins.length > 1) {
      throw new UnsupportedError("ClassMirror.mixin not yet supported for "
        "classes ($_cls) with multiple mixins");
    }
    _mixin = reflectType(_wrap(mixins[0]));
    return _mixin;
  }

  String toString() => "ClassMirror on '$_cls'";
}

class JsVariableMirror extends JsMirror implements VariableMirror {
  final Symbol _symbol;
  final String _name;
  final TypeMirror type;
  final List<InstanceMirror> metadata;

  // TODO(vsm): Refactor this out.
  Symbol get simpleName => _symbol;

  // TODO(vsm): Fix this
  final bool isStatic = false;
  final bool isFinal = false;

  JsVariableMirror._(Symbol symbol, Type t, List annotations)
      : _symbol = symbol,
        _name = getName(symbol),
        type = reflectType(t),
        metadata = new List<InstanceMirror>.unmodifiable(
            annotations.map((a) => reflect(a)));

  String toString() => "VariableMirror on '$_name'";
}

class JsParameterMirror extends JsVariableMirror implements ParameterMirror {
  JsParameterMirror._(Symbol member, Type t, List annotations)
      : super._(member, t, annotations);

  String toString() => "ParameterMirror on '$_name'";
}

class JsMethodMirror extends JsMirror implements MethodMirror {
  final Symbol _symbol;
  final String _name;
  List<ParameterMirror> _params;
  List<InstanceMirror> _metadata;
  final bool isConstructor;
  final bool isStatic;

  // TODO(vsm): Fix this
  final bool isFinal = false;
  bool get isSetter => _name.endsWith('=');
  bool get isPrivate => _name.startsWith('_');

  // TODO(vsm): Refactor this out.
  Symbol get simpleName => _symbol;

  JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype)
    : _symbol = symbol, _name = getName(symbol), isConstructor = true, isStatic = false {
      _createParameterMirrorList(ftype);
  }

  JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype)
    : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = false {
      _createParameterMirrorList(ftype);
  }

  JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype)
    : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic = true {
      _createParameterMirrorList(ftype);
  }

  // TODO(vsm): Support named constructors.
  Symbol get constructorName => isConstructor ? _symbol : null;
  List<ParameterMirror> get parameters => _params;
  List<InstanceMirror> get metadata => _metadata;

  void _createParameterMirrorList(ftype) {
    if (ftype == null) {
      // TODO(vsm): No explicit constructor.  Verify this.
      _params = const [];
      _metadata = const [];
      return;
    }

    // TODO(vsm): Why does generic function type trigger true for List?
    if (ftype is! Function && ftype is List) {
      // Record metadata
      _metadata = new List<InstanceMirror>.unmodifiable(
          ftype.skip(1).map((a) => reflect(a)));
      ftype = ftype[0];
    } else {
      _metadata = const [];
    }

    // TODO(vsm): Handle generic function types properly.  Or deprecate mirrors
    // before we need to!
    if (JS('bool', 'typeof(#) == "function"', ftype)) {
      // Instantiate the generic version.
      // TODO(vsm): Can't use arguments.length on arrow function.
      ftype = JS('', '#.apply(null, #)', ftype, [dynamic, dynamic, dynamic]);
    }

    // TODO(vsm): Add named args.
    List args = ftype.args;
    List opts = ftype.optionals;
    var params = new List<ParameterMirror>(args.length + opts.length);

    for (var i = 0; i < args.length; ++i) {
      var type = args[i];
      var metadata = ftype.metadata[i];
      // TODO(vsm): Recover the param name.
      var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata);
      params[i] = param;
    }

    for (var i = 0; i < opts.length; ++i) {
      var type = opts[i];
      var metadata = ftype.metadata[args.length + i];
      // TODO(vsm): Recover the param name.
      var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata);
      params[i + args.length] = param;
    }

    _params = new List.unmodifiable(params);
  }

  String toString() => "MethodMirror on '$_name'";
}
