// Copyright (c) 2012, 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.

// Patch library for dart:mirrors.

import 'dart:_foreign_helper' show JS;
import "dart:_collection-dev" as _symbol_dev;

// Yeah, seriously: mirrors in dart2js are experimental...
const String _MIRROR_OPT_IN_MESSAGE = """

This program is using an experimental feature called \"mirrors\".  As
currently implemented, mirrors do not work with minification, and will
cause spurious errors depending on how code was optimized.

The authors of this program are aware of these problems and have
decided the thrill of using an experimental feature is outweighing the
risks.  Furthermore, the authors of this program understand that
long-term, to fix the problems mentioned above, mirrors may have
negative impact on size and performance of Dart programs compiled to
JavaScript.
""";

bool _mirrorsEnabled = false;

patch class MirrorSystem {
  patch static String getName(Symbol symbol) {
    return _symbol_dev.Symbol.getName(symbol);
  }
}

/**
 * Stub class for the mirror system.
 */
patch MirrorSystem currentMirrorSystem() {
  _ensureEnabled();
  throw new UnsupportedError("MirrorSystem not implemented");
}

patch Future<MirrorSystem> mirrorSystemOf(SendPort port) {
  _ensureEnabled();
  throw new UnsupportedError("MirrorSystem not implemented");
}

patch InstanceMirror reflect(Object reflectee) {
  if (!_mirrorsEnabled && (_MIRROR_OPT_IN_MESSAGE == reflectee)) {
    // Turn on mirrors and warn that it is an experimental feature.
    _mirrorsEnabled = true;
    print(reflectee);
  }
  return new _InstanceMirror(reflectee);
}

patch ClassMirror reflectClass(Type key) {
  throw new UnimplementedError('reflectClass is not yet implemented'
                               'in dart2js');
}

class _InstanceMirror extends InstanceMirror {
  static final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>();

  final reflectee;

  _InstanceMirror(this.reflectee);

  bool get hasReflectee => true;

  ClassMirror get type {
    _ensureEnabled();
    String className = Primitives.objectTypeName(reflectee);
    var constructor = Primitives.getConstructor(className);
    var mirror = classMirrors[constructor];
    if (mirror == null) {
      mirror = new _ClassMirror(className, constructor);
      classMirrors[constructor] = mirror;
    }
    return mirror;
  }

  Future<InstanceMirror> invokeAsync(String memberName,
                                     List<Object> positionalArguments,
                                     [Map<String,Object> namedArguments]) {
    _ensureEnabled();
    if (namedArguments != null && !namedArguments.isEmpty) {
      throw new UnsupportedError('Named arguments are not implemented');
    }
    // Copy the list to ensure that it can safely be passed to
    // JavaScript.
    var jsList = new List.from(positionalArguments);
    var mangledName = '${memberName}\$${positionalArguments.length}';
    var method = JS('var', '#[#]', reflectee, mangledName);
    var completer = new Completer<InstanceMirror>();
    // TODO(ahe): [Completer] or [Future] should have API to create a
    // delayed action.  Simulating with a [Timer].
    Timer.run(() {
      if (JS('String', 'typeof #', method) == 'function') {
        var result =
            JS('var', '#.apply(#, #)', method, reflectee, jsList);
        completer.complete(new _InstanceMirror(result));
      } else {
        completer.completeError('not a method $memberName');
      }
    });
    return completer.future;
  }

  delegate(Invocation invocation) {
    return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
  }

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

class _ClassMirror extends ClassMirror {
  final String _name;
  final _jsConstructor;

  _ClassMirror(this._name, this._jsConstructor) {
    _ensureEnabled();
  }

  String toString() => 'ClassMirror($_name)';
}

_ensureEnabled() {
  if (_mirrorsEnabled) return;
  throw new UnsupportedError('dart:mirrors is an experimental feature');
}
