// 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.
//
// Dart test program for checking implemention of MirrorSystem when
// inspecting the current isolate.
//
// VMOptions=--enable_type_checks

library isolate_mirror_local_test;

import "package:expect/expect.dart";
import 'dart:async';
import 'dart:isolate';
import 'dart:mirrors';

ReceivePort exit_port;
Set expectedTests;

void testDone(String test) {
  if (!expectedTests.contains(test)) {
    throw "Unexpected test name '$test'";
  }
  expectedTests.remove(test);
  if (expectedTests.isEmpty) {
    // All tests are done.
    exit_port.close();
  }
}

int global_var = 0;
final int final_global_var = 0;

// Top-level getter and setter.
int get myVar { return 5; }
void set myVar(x) {}

// This function will be invoked reflectively.
int function(int x) {
  global_var = x;
  return x + 1;
}

typedef void FuncType(String a);

FuncType myFunc = null;

_stringCompare(String a, String b) => a.compareTo(b);
sort(list) => list.sort(_stringCompare);

String buildMethodString(MethodMirror func) {
  var result = '${MirrorSystem.getName(func.simpleName)} '
      'return(${MirrorSystem.getName(func.returnType.simpleName)})';
  if (func.isPrivate) {
    result = '$result private';
  }
  if (func.isTopLevel) {
    result = '$result toplevel';
  }
  if (func.isStatic) {
    result = '$result static';
  }
  if (func.isAbstract) {
    result = '$result abstract';
  }
  if (func.isRegularMethod) {
    result = '$result method';
  }
  if (func.isGetter) {
    result = '$result getter';
  }
  if (func.isSetter) {
    result = '$result setter';
  }
  if (func.isConstructor) {
    result = '$result constructor';
  }
  if (func.isConstConstructor) {
    result = '$result const';
  }
  if (func.isGenerativeConstructor) {
    result = '$result generative';
  }
  if (func.isRedirectingConstructor) {
    result = '$result redirecting';
  }
  if (func.isFactoryConstructor) {
    result = '$result factory';
  }
  return result;
}

String buildVariableString(VariableMirror variable) {
  var result = '${MirrorSystem.getName(variable.simpleName)} '
      'type(${MirrorSystem.getName(variable.type.simpleName)})';
  if (variable.isPrivate) {
    result = '$result private';
  }
  if (variable.isTopLevel) {
    result = '$result toplevel';
  }
  if (variable.isStatic) {
    result = '$result static';
  }
  if (variable.isFinal) {
    result = '$result final';
  }
  return result;
}

void testRootLibraryMirror(LibraryMirror lib_mirror) {
  Expect.equals(const Symbol('isolate_mirror_local_test'),
                lib_mirror.simpleName);
  Expect.equals(const Symbol('isolate_mirror_local_test'),
                lib_mirror.qualifiedName);
  Expect.equals(null, lib_mirror.owner);
  Expect.isFalse(lib_mirror.isPrivate);
  Expect.isTrue(lib_mirror.uri.path.contains('isolate_mirror_local_test.dart'));
  Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
                lib_mirror.toString());

  // Test library invocation by calling function(123).
  Expect.equals(0, global_var);
  lib_mirror.invokeAsync(const Symbol('function'), [123]).then(
      (InstanceMirror retval) {
        Expect.equals(123, global_var);
        testImplements(retval.type, #int);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals(124, retval.reflectee);
        testDone('testRootLibraryMirror');
      });

  // Check that the members map is complete.
  List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('['
                'FuncType, '
                'GenericClass, '
                'MyClass, '
                'MyException, '
                'MyInterface, '
                'MySuperClass, '
                '_stringCompare, '
                'buildMethodString, '
                'buildVariableString, '
                'exit_port, '
                'expectedTests, '
                'final_global_var, '
                'function, '
                'global_var, '
                'main, '
                'methodWithError, '
                'methodWithException, '
                'myFunc, '
                'myVar, '
                'myVar=, '
                'sort, '
                'testBoolInstanceMirror, '
                'testCustomInstanceMirror, '
                'testDone, '
                'testImplements, '
                'testIntegerInstanceMirror, '
                'testLibrariesMap, '
                'testMirrorErrors, '
                'testMirrorSystem, '
                'testNullInstanceMirror, '
                'testRootLibraryMirror, '
                'testStringInstanceMirror]',
                '$keys');

  // Check that the classes map is complete.
  keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('['
                'FuncType, '
                'GenericClass, '
                'MyClass, '
                'MyException, '
                'MyInterface, '
                'MySuperClass]',
                '$keys');

  // Check that the functions map is complete.
  keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('['
                '_stringCompare, '
                'buildMethodString, '
                'buildVariableString, '
                'function, '
                'main, '
                'methodWithError, '
                'methodWithException, '
                'myVar, '
                'myVar=, '
                'sort, '
                'testBoolInstanceMirror, '
                'testCustomInstanceMirror, '
                'testDone, '
                'testImplements, '
                'testIntegerInstanceMirror, '
                'testLibrariesMap, '
                'testMirrorErrors, '
                'testMirrorSystem, '
                'testNullInstanceMirror, '
                'testRootLibraryMirror, '
                'testStringInstanceMirror]',
                '$keys');

  // Check that the getters map is complete.
  keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('[myVar]', '$keys');

  // Check that the setters map is complete.
  keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('[myVar=]', '$keys');

  // Check that the variables map is complete.
  keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList();
  sort(keys);
  Expect.equals('['
                'exit_port, '
                'expectedTests, '
                'final_global_var, '
                'global_var, '
                'myFunc]',
                '$keys');

  ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')];
  ClassMirror generic_cls_mirror =
      lib_mirror.members[const Symbol('GenericClass')];

  // Test function mirrors.
  MethodMirror func = lib_mirror.members[const Symbol('function')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('function return(int) toplevel static method',
                buildMethodString(func));

  func = lib_mirror.members[const Symbol('myVar')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('myVar return(int) toplevel static getter',
                buildMethodString(func));

  func = lib_mirror.members[const Symbol('myVar=')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('myVar= return(void) toplevel static setter',
                buildMethodString(func));

  func = cls_mirror.members[const Symbol('method')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('method return(int) method', buildMethodString(func));

  func = cls_mirror.constructors[const Symbol('MyClass')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('MyClass return(MyClass) constructor generative',
                buildMethodString(func));

  func = cls_mirror.constructors[const Symbol('MyClass.named')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('MyClass.named return(MyClass) constructor generative',
                buildMethodString(func));

  func = generic_cls_mirror.members[const Symbol('method')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('method return(T) method', buildMethodString(func));

  // Test variable mirrors.
  VariableMirror variable = lib_mirror.members[const Symbol('global_var')];
  Expect.isTrue(variable is VariableMirror);
  Expect.equals('global_var type(int) toplevel static',
                buildVariableString(variable));

  variable = lib_mirror.members[const Symbol('final_global_var')];
  Expect.isTrue(variable is VariableMirror);
  Expect.equals('final_global_var type(int) toplevel static final',
                buildVariableString(variable));

  variable = cls_mirror.members[const Symbol('value')];
  Expect.isTrue(variable is VariableMirror);
  Expect.equals('value type(dynamic) final', buildVariableString(variable));

  // Test type variable mirrors.
  var type_var = generic_cls_mirror.members[const Symbol('method')].returnType;
  Expect.isTrue(type_var is TypeVariableMirror);
  Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName);
  Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName);

  // Test typedef mirrors.
  var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type;
  Expect.isTrue(typedef_mirror is TypedefMirror);
  Expect.equals(const Symbol('isolate_mirror_local_test'),
                typedef_mirror.owner.simpleName);

  // Test function type mirrors.
  var func_cls_mirror = typedef_mirror.referent;
  Expect.isTrue(func_cls_mirror is FunctionTypeMirror);
  // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
  Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName);
}

void testLibrariesMap(Map libraries) {
  // Just look for a couple of well-known libs.
  LibraryMirror core_lib = libraries[Uri.parse('dart:core')];
  Expect.isTrue(core_lib is LibraryMirror);

  LibraryMirror mirror_lib = libraries[Uri.parse('dart:mirrors')];
  Expect.isTrue(mirror_lib is LibraryMirror);

  // Lookup an interface from a library and make sure it is sane.
  ClassMirror list_intf = core_lib.members[const Symbol('List')];
  Expect.isTrue(list_intf is ClassMirror);
  Expect.equals(const Symbol('List'), list_intf.simpleName);
  Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName);
  Expect.isFalse(list_intf.isPrivate);
  Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName);
  Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName);
  Expect.isTrue(list_intf.isClass);
  Expect.equals(const Symbol('Iterable'),
                list_intf.superinterfaces[0].simpleName);
  Expect.equals("ClassMirror on 'List'", list_intf.toString());

  // Lookup a class from a library and make sure it is sane.
  ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
  Expect.isTrue(oom_cls is ClassMirror);
  Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName);
  Expect.equals(const Symbol('dart.core.OutOfMemoryError'),
                oom_cls.qualifiedName);
  Expect.isFalse(oom_cls.isPrivate);
  Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName);
  Expect.isTrue(oom_cls.defaultFactory == null);
  Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
  Expect.isTrue(oom_cls.isClass);
  Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
  Expect.equals("ClassMirror on 'OutOfMemoryError'",
                oom_cls.toString());
  testDone('testLibrariesMap');
}

void testMirrorSystem(MirrorSystem mirrors) {
  Expect.isTrue(mirrors.isolate.debugName.contains('main'));
  testRootLibraryMirror(mirrors.isolate.rootLibrary);
  testLibrariesMap(mirrors.libraries);
  Expect.equals(const Symbol('void'), mirrors.voidType.simpleName);
  Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName);
  Expect.isTrue(mirrors.voidType is TypeMirror);
  Expect.isTrue(mirrors.dynamicType is TypeMirror);
  Expect.isFalse(mirrors.voidType is ClassMirror);
  Expect.isFalse(mirrors.dynamicType is ClassMirror);
  testDone('testMirrorSystem');
}

void testImplements(klass, intfName) {
  bool foundInterface = false;
  for (ClassMirror cm = klass; cm != null; cm = cm.superclass) {
    if (cm.simpleName == intfName) foundInterface = true;
    cm.superinterfaces.forEach((intf) {
      if (intf.simpleName == intfName) foundInterface = true;
    });
  }
  Expect.isTrue(foundInterface, '$klass should implement $intfName');
}

void testIntegerInstanceMirror(InstanceMirror mirror) {
  testImplements(mirror.type, #int);
  Expect.isTrue(mirror.hasReflectee);
  Expect.equals(1001, mirror.reflectee);
  Expect.equals("InstanceMirror on 1001", mirror.toString());

  // Invoke (mirror + mirror).
  mirror.invokeAsync(const Symbol('+'), [ mirror ]).then(
      (InstanceMirror retval) {
        testImplements(retval.type, #int);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals(2002, retval.reflectee);
        testDone('testIntegerInstanceMirror');
      });
}

void testStringInstanceMirror(InstanceMirror mirror) {
  testImplements(mirror.type, #String);
  Expect.isTrue(mirror.hasReflectee);
  Expect.equals('This\nis\na\nString', mirror.reflectee);
  Expect.equals('InstanceMirror on "This\\nis\\na\\nString"',
                mirror.toString());

  // Invoke mirror[0].
  mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then(
      (InstanceMirror retval) {
        testImplements(retval.type, #String);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals('T', retval.reflectee);
        testDone('testStringInstanceMirror');
      });
}

void testBoolInstanceMirror(InstanceMirror mirror) {
  testImplements(mirror.type, #bool);
  Expect.isTrue(mirror.hasReflectee);
  Expect.equals(true, mirror.reflectee);
  Expect.equals("InstanceMirror on true", mirror.toString());
  testDone('testBoolInstanceMirror');
}

void testNullInstanceMirror(InstanceMirror mirror) {
  testImplements(mirror.type, #Null);
  Expect.isTrue(mirror.hasReflectee);
  Expect.equals(null, mirror.reflectee);
  Expect.equals("InstanceMirror on null", mirror.toString());
  testDone('testNullInstanceMirror');
}

class MySuperClass {
}

class MyInterface {
}

@notDefined
class MyClass extends MySuperClass implements MyInterface {
  MyClass(this.value) {}
  MyClass.named() {}

  final value;

  int method(int arg) {
    return arg + value;
  }
}

class GenericClass<T> {
  T method(int arg) {
    return null;
  }
}

void testCustomInstanceMirror(InstanceMirror mirror) {
  Expect.isTrue(mirror.hasReflectee);
  bool saw_exception = false;
  try {
    mirror.reflectee;
  } on MirrorException catch (me) {
    saw_exception = true;
  }
  Expect.isFalse(saw_exception);
  Expect.equals("InstanceMirror on Instance of 'MyClass'",
                mirror.toString());

  ClassMirror cls = mirror.type;
  Expect.isTrue(cls is ClassMirror);
  Expect.equals(const Symbol('MyClass'), cls.simpleName);
  Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
  Expect.isTrue(cls.defaultFactory == null);
  Expect.equals(const Symbol('isolate_mirror_local_test'),
                cls.owner.simpleName);
  Expect.isTrue(cls.isClass);
  Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
  Expect.throws(() => cls.metadata,
                (e) => e is MirroredCompilationError,
                'Bad metadata');
  Expect.equals("ClassMirror on 'MyClass'", cls.toString());

  // Invoke mirror.method(1000).
  mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
      (InstanceMirror retval) {
        testImplements(retval.type, #int);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals(1017, retval.reflectee);
        testDone('testCustomInstanceMirror');
      });

}

class MyException implements Exception {
  MyException(this._message);
  final String _message;
  String toString() { return 'MyException: $_message'; }
}

void methodWithException() {
  throw new MyException("from methodWithException");
}

void methodWithError() {
  // We get a parse error when we try to run this function.
  +++;
}

void testMirrorErrors(MirrorSystem mirrors) {
  LibraryMirror lib_mirror = mirrors.isolate.rootLibrary;

  lib_mirror.invokeAsync(const Symbol('methodWithException'), [])
    .then((InstanceMirror retval) {
      // Should not reach here.
      Expect.isTrue(false);
    })
    .catchError((error) {
        Expect.isTrue(error is MyException);
        Expect.equals('MyException: from methodWithException',
                      error.toString());
        testDone('testMirrorErrors1');
      });

  lib_mirror.invokeAsync(const Symbol('methodWithError'), [])
    .then((InstanceMirror retval) {
      // Should not reach here.
      Expect.isTrue(false);
    })
    .catchError((error) {
      Expect.isTrue(error is MirroredCompilationError);
      Expect.isTrue(error.message.contains('unexpected token'));
      testDone('testMirrorErrors2');
    });

  // TODO(turnidge): When we call a method that doesn't exist, we
  // should probably call noSuchMethod().  I'm adding this test to
  // document the current behavior in the meantime.
  lib_mirror.invokeAsync(const Symbol('methodNotFound'), [])
    .then((InstanceMirror retval) {
      // Should not reach here.
      Expect.isTrue(false);
    })
    .catchError((error) {
      Expect.isTrue(error is NoSuchMethodError);
      Expect.isTrue(error.toString().contains(
          "No top-level method 'methodNotFound'"));
      testDone('testMirrorErrors3');
    });
}

void main() {
  // When all of the expected tests complete, the exit_port is closed,
  // allowing the program to terminate.
  exit_port = new ReceivePort();
  expectedTests = new Set<String>.from(['testRootLibraryMirror',
                                        'testLibrariesMap',
                                        'testMirrorSystem',
                                        'testIntegerInstanceMirror',
                                        'testStringInstanceMirror',
                                        'testBoolInstanceMirror',
                                        'testNullInstanceMirror',
                                        'testCustomInstanceMirror',
                                        'testMirrorErrors1',
                                        'testMirrorErrors2',
                                        'testMirrorErrors3']);

  // Test that an isolate can reflect on itself.
  mirrorSystemOf(exit_port.toSendPort()).then(testMirrorSystem);

  testIntegerInstanceMirror(reflect(1001));
  testStringInstanceMirror(reflect('This\nis\na\nString'));
  testBoolInstanceMirror(reflect(true));
  testNullInstanceMirror(reflect(null));
  testCustomInstanceMirror(reflect(new MyClass(17)));
  testMirrorErrors(currentMirrorSystem());
}
