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

// @dart = 2.6

library dart._js_mirrors;

import 'dart:mirrors';
import 'dart:_runtime' as dart;
import 'dart:_foreign_helper' show JS;
import 'dart:_internal' as _internal show Symbol;
import 'dart:_js_helper' show PrivateSymbol;

String getName(Symbol symbol) {
  if (symbol is PrivateSymbol) {
    return PrivateSymbol.getName(symbol);
  } else {
    return _internal.Symbol.getName(symbol as _internal.Symbol);
  }
}

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

final currentJsMirrorSystem = JsMirrorSystem();

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 JsClosureMirror._(reflectee);
  } else {
    return JsInstanceMirror._(reflectee);
  }
}

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

typedef T _Lazy<T>();

dynamic _getESSymbol(Symbol symbol) => PrivateSymbol.getNativeSymbol(symbol);

dynamic _getMember(Symbol symbol) {
  var privateSymbol = _getESSymbol(symbol);
  if (privateSymbol != null) {
    return privateSymbol;
  }
  var name = getName(symbol);
  // TODO(jacobr): this code is duplicated in code_generator.dart
  switch (name) {
    case '[]':
      name = '_get';
      break;
    case '[]=':
      name = '_set';
      break;
    case 'unary-':
      name = '_negate';
      break;
    case 'constructor':
    case 'prototype':
      name = '_$name';
      break;
  }
  return name;
}

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 PrivateSymbol(name, member);
}

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

Map<Symbol, dynamic> _toDartMap(data) {
  if (data == null) return {};
  var map = 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 = 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;
}

dynamic _runtimeType(obj) => dart.wrapType(dart.getReifiedType(obj));

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

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

class JsMirrorSystem implements MirrorSystem {
  get libraries => const {};

  noSuchMethod(Invocation i) {
    _unimplemented(this.runtimeType, i);
  }
}

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;
  }

  InstanceMirror getField(Symbol symbol) {
    var name = _getMember(symbol);
    var field = dart.dloadMirror(reflectee, name);
    return reflect(field);
  }

  InstanceMirror setField(Symbol symbol, Object value) {
    var name = _getMember(symbol);
    dart.dputMirror(reflectee, name, value);
    return reflect(value);
  }

  InstanceMirror invoke(Symbol symbol, List<dynamic> args,
      [Map<Symbol, dynamic> namedArgs]) {
    var name = _getMember(symbol);
    var result =
        dart.callMethod(reflectee, name, null, args, _toJsMap(namedArgs), name);
    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]) {
    var result = dart.dcall(reflectee, args, _toJsMap(namedArgs));
    return reflect(result);
  }
}

// For generic classes, mirrors uses the same representation, [ClassMirror],
// for the instantiated and uninstantiated type.  Somewhat awkwardly, most APIs
// (e.g., [newInstance]) treat the uninstantiated type as if instantiated
// with all dynamic.  The representation below is correspondingly a bit wonky.
// For an uninstantiated generic class, [_cls] is the instantiated type (with
// dynamic) and [_raw] is null.  For an instantiated generic class, [_cls] is
// the instantiated type (with the corresponding type parameters), and [_raw]
// is the generic factory.
class JsClassMirror extends JsMirror implements ClassMirror {
  final Type _cls;
  final Symbol simpleName;
  // Generic class factory for instantiated types.
  final dynamic _raw;

  ClassMirror _originalDeclaration;

  // 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 = dart.unwrapType(_cls);
      // Only get metadata directly embedded on this class, not its
      // superclasses.
      Function fn = JS(
          '',
          'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
          unwrapped,
          unwrapped);
      _metadata = (fn == null)
          ? const <InstanceMirror>[]
          : 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 = Map<Symbol, DeclarationMirror>();
      var unwrapped = dart.unwrapType(_cls);
      var constructors = _toDartMap(dart.getConstructors(unwrapped));
      constructors.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] = JsMethodMirror._constructor(this, symbol, ft);
      });
      if (constructors.isEmpty) {
        // Add a default
        var name = 'new';
        var ft = dart.fnType(dart.unwrapType(_cls), []);
        var symbol = Symbol(name);
        _declarations[symbol] = JsMethodMirror._constructor(this, symbol, ft);
      }
      var fields = _toDartMap(dart.getFields(unwrapped));
      fields.forEach((symbol, t) {
        _declarations[symbol] = JsVariableMirror._fromField(symbol, t);
      });
      var methods = _toDartMap(dart.getMethods(unwrapped));
      methods.forEach((symbol, ft) {
        var name = getName(symbol);
        _declarations[symbol] =
            JsMethodMirror._instanceMethod(this, symbol, ft);
      });

      getterType(type) {
        if (JS<bool>('!', '# instanceof Array', type)) {
          var array = JS('', '#.slice()', type);
          type = JS('', '#[0]', array);
          JS('', '#[0] = #', array, dart.fnType(type, []));
          return array;
        } else {
          return dart.fnType(type, []);
        }
      }

      var getters = _toDartMap(dart.getGetters(unwrapped));
      getters.forEach((symbol, type) {
        _declarations[symbol] =
            JsMethodMirror._instanceMethod(this, symbol, getterType(type));
      });

      setterType(type) {
        if (JS<bool>('!', '# instanceof Array', type)) {
          var array = JS('', '#.slice()', type);
          type = JS('', '#[0]', array);
          JS('', '#[0] = #', array, dart.fnType(dart.void_, [type]));
          return array;
        } else {
          return dart.fnType(dart.void_, [type]);
        }
      }

      var setters = _toDartMap(dart.getSetters(unwrapped));
      setters.forEach((symbol, type) {
        var name = getName(symbol) + '=';
        // Create a separate symbol for the setter.
        symbol = PrivateSymbol(name, _getESSymbol(symbol));
        _declarations[symbol] =
            JsMethodMirror._instanceMethod(this, symbol, setterType(type));
      });

      var staticFields = _toDartMap(dart.getStaticFields(unwrapped));
      staticFields.forEach((symbol, t) {
        _declarations[symbol] = JsVariableMirror._fromField(symbol, t);
      });
      var statics = _toDartMap(dart.getStaticMethods(unwrapped));
      statics.forEach((symbol, ft) {
        _declarations[symbol] = JsMethodMirror._staticMethod(this, symbol, ft);
      });

      var staticGetters = _toDartMap(dart.getStaticGetters(unwrapped));
      staticGetters.forEach((symbol, type) {
        _declarations[symbol] =
            JsMethodMirror._staticMethod(this, symbol, getterType(type));
      });

      var staticSetters = _toDartMap(dart.getStaticSetters(unwrapped));
      staticSetters.forEach((symbol, type) {
        _declarations[symbol] =
            JsMethodMirror._staticMethod(this, symbol, setterType(type));
      });
      _declarations =
          Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
    }
    return _declarations;
  }

  JsClassMirror._(Type cls, {bool instantiated = true})
      : _cls = cls,
        _raw = instantiated ? dart.getGenericClass(dart.unwrapType(cls)) : null,
        simpleName = Symbol(JS<String>('!', '#.name', dart.unwrapType(cls))) {
    var typeArgs = dart.getGenericArgs(dart.unwrapType(_cls));
    if (typeArgs == null) {
      _typeArguments = const [];
    } else {
      _typeArguments =
          List.unmodifiable(typeArgs.map((t) => reflectType(dart.wrapType(t))));
    }
  }

  InstanceMirror newInstance(Symbol constructorName, List args,
      [Map<Symbol, dynamic> namedArgs]) {
    // TODO(vsm): Support named arguments.
    var name = getName(constructorName);
    assert(namedArgs == null || namedArgs.isEmpty);
    // Default constructors are mapped to new.
    if (name == '') name = 'new';
    var cls = dart.unwrapType(_cls);
    var ctr = JS('', '#.#', cls, name);
    // Only generative Dart constructors are wired up as real JS constructors.
    var instance = JS<bool>('!', '#.prototype == #.prototype', cls, ctr)
        // Generative
        ? JS('', 'new #(...#)', ctr, args)
        // Factory
        : JS('', '#(...#)', ctr, 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('', '#[#]', dart.unwrapType(_cls), name));
  }

  InstanceMirror setField(Symbol symbol, Object value) {
    var name = getName(symbol);
    JS('', '#[#] = #', dart.unwrapType(_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 = List.from(args);
      args.add(_toJsMap(namedArgs));
    }
    var result = JS('', '#.#(...#)', dart.unwrapType(_cls), name, args);
    return reflect(result);
  }

  List<ClassMirror> get superinterfaces {
    _Lazy<List<Type>> interfaceThunk =
        JS('', '#[dart.implements]', dart.unwrapType(_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 {
    if (_raw == null) {
      return this;
    }
    if (_originalDeclaration != null) {
      return _originalDeclaration;
    }
    _originalDeclaration = JsClassMirror._(dart.wrapType(JS('', '#()', _raw)),
        instantiated: false);
    return _originalDeclaration;
  }

  ClassMirror get superclass {
    if (_cls == Object) {
      return null;
    } else {
      return reflectType(
          dart.wrapType(JS<Type>('!', '#.__proto__', dart.unwrapType(_cls))));
    }
  }

  ClassMirror get mixin {
    if (_mixin != null) {
      return _mixin;
    }
    var mixin = dart.getMixin(dart.unwrapType(_cls));
    if (mixin == null) {
      // If there is no mixin, return this mirror per API.
      _mixin = this;
      return _mixin;
    }
    _mixin = reflectType(dart.wrapType(mixin));
    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;
  final bool isFinal;

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

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

  JsVariableMirror._(Symbol symbol, Type t, List annotations,
      {this.isFinal = false})
      : _symbol = symbol,
        _name = getName(symbol),
        type = reflectType(t),
        metadata =
            List<InstanceMirror>.unmodifiable(annotations?.map(reflect) ?? []);

  JsVariableMirror._fromField(Symbol symbol, fieldInfo)
      : this._(symbol, dart.wrapType(JS('', '#.type', fieldInfo)),
            JS('', '#.metadata', fieldInfo),
            isFinal: JS<bool>('!', '#.isFinal', fieldInfo));

  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 = 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!
    ftype = dart.getFunctionTypeMirror(ftype);

    // TODO(vsm): Add named args.
    List args = ftype.args;
    List opts = ftype.optionals;
    var params = 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 =
          JsParameterMirror._(Symbol(''), dart.wrapType(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 =
          JsParameterMirror._(Symbol(''), dart.wrapType(type), metadata);
      params[i + args.length] = param;
    }

    _params = List.unmodifiable(params);
  }

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