// 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);
        Expect.equals(const Symbol('int'), retval.type.simpleName);
        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, '
                '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, '
                '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', buildMethodString(func));

  func = cls_mirror.constructors[const Symbol('MyClass.named')];
  Expect.isTrue(func is MethodMirror);
  Expect.equals('MyClass.named return(MyClass) constructor',
                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 testIntegerInstanceMirror(InstanceMirror mirror) {
  Expect.equals(const Symbol('int'), mirror.type.simpleName);
  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) {
        Expect.equals(const Symbol('int'), retval.type.simpleName);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals(2002, retval.reflectee);
        testDone('testIntegerInstanceMirror');
      });
}

void testStringInstanceMirror(InstanceMirror mirror) {
  Expect.equals(const Symbol('String'), mirror.type.simpleName);
  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) {
        Expect.equals(const Symbol('String'), retval.type.simpleName);
        Expect.isTrue(retval.hasReflectee);
        Expect.equals('T', retval.reflectee);
        testDone('testStringInstanceMirror');
      });
}

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

void testNullInstanceMirror(InstanceMirror mirror) {
  Expect.equals(const Symbol('Null'), mirror.type.simpleName);
  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) {
        Expect.equals(const Symbol('int'), retval.type.simpleName);
        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());
}
