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

// This tests uses the multi-test "ok" feature:
// none: Trimmed behaviour. Passing on the VM.
// 01: Trimmed version for dart2js.
// 02: Full version passing in the VM.
//
// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.

library test.class_equality_test;

import 'dart:mirrors';

import 'package:expect/expect.dart';

class A<T> {}

class B extends A<int> {}

class BadEqualityHash {
  int count = 0;
  bool operator ==(other) => true;
  int get hashCode => count++;
}

typedef bool Predicate(Object o);
Predicate somePredicate = (Object o) => false;

checkEquality(List<Map<String, Object>> equivalenceClasses) {
  for (var equivalenceClass in equivalenceClasses) {
    equivalenceClass.forEach((name, member) {
      equivalenceClass.forEach((otherName, otherMember) {
        // Reflexivity, symmetry and transitivity.
        Expect.equals(member, otherMember, "$name == $otherName");
        Expect.equals(member.hashCode, otherMember.hashCode,
            "$name.hashCode == $otherName.hashCode");
      });
      for (var otherEquivalenceClass in equivalenceClasses) {
        if (otherEquivalenceClass == equivalenceClass) continue;
        otherEquivalenceClass.forEach((otherName, otherMember) {
          Expect.notEquals(
              member, otherMember, "$name != $otherName"); // Exclusion.
          // Hash codes may or may not be equal.
        });
      }
    });
  }
}

void subroutine() {}

main() {
  LibraryMirror thisLibrary = currentMirrorSystem()
      .findLibrary(const Symbol('test.class_equality_test'));

  var o1 = new Object();
  var o2 = new Object();

  var badEqualityHash1 = new BadEqualityHash();
  var badEqualityHash2 = new BadEqualityHash();

  checkEquality(<Map<String, Object>>[
    {'reflect(o1)': reflect(o1), 'reflect(o1), again': reflect(o1)},
    {'reflect(o2)': reflect(o2), 'reflect(o2), again': reflect(o2)},
    {
      'reflect(badEqualityHash1)': reflect(badEqualityHash1),
      'reflect(badEqualityHash1), again': reflect(badEqualityHash1)
    },
    {
      'reflect(badEqualityHash2)': reflect(badEqualityHash2),
      'reflect(badEqualityHash2), again': reflect(badEqualityHash2)
    },
    {'reflect(true)': reflect(true), 'reflect(true), again': reflect(true)},
    {'reflect(false)': reflect(false), 'reflect(false), again': reflect(false)},
    {'reflect(null)': reflect(null), 'reflect(null), again': reflect(null)},
    {
      'reflect(3.5+4.5)': reflect(3.5 + 4.5),
      'reflect(6.5+1.5)': reflect(6.5 + 1.5)
    },
    {'reflect(3+4)': reflect(3 + 4), 'reflect(6+1)': reflect(6 + 1)},
    {'reflect("foo")': reflect("foo"), 'reflect("foo"), again': reflect("foo")},
    {
      'currentMirrorSystem().voidType': currentMirrorSystem().voidType,
      'thisLibrary.declarations[#subroutine].returnType':
          (thisLibrary.declarations[#subroutine] as MethodMirror).returnType
    },
    {
      'currentMirrorSystem().dynamicType': currentMirrorSystem().dynamicType,
      'thisLibrary.declarations[#main].returnType':
          (thisLibrary.declarations[#main] as MethodMirror).returnType
    },
    {
      'reflectClass(A)': reflectClass(A),
      'thisLibrary.declarations[#A]': thisLibrary.declarations[#A],
      'reflect(new A<int>()).type.originalDeclaration':
          reflect(new A<int>()).type.originalDeclaration
    },
    {
      'reflectClass(B).superclass': reflectClass(B).superclass,
      'reflect(new A<int>()).type': reflect(new A<int>()).type
    },
    {
      'reflectClass(B)': reflectClass(B),
      'thisLibrary.declarations[#B]': thisLibrary.declarations[#B],
      'reflect(new B()).type': reflect(new B()).type
    },
    {
      'reflectClass(BadEqualityHash).declarations[#==]':
          reflectClass(BadEqualityHash).declarations[#==],
      'reflect(new BadEqualityHash()).type.declarations[#==]':
          reflect(new BadEqualityHash()).type.declarations[#==]
    },
    {
      'reflectClass(BadEqualityHash).declarations[#==].parameters[0]':
          (reflectClass(BadEqualityHash).declarations[#==] as MethodMirror)
              .parameters[0],
      'reflect(new BadEqualityHash()).type.declarations[#==].parameters[0]':
          (reflect(new BadEqualityHash()).type.declarations[#==]
                  as MethodMirror)
              .parameters[0]
    },
    {
      'reflectClass(BadEqualityHash).declarations[#count]':
          reflectClass(BadEqualityHash).declarations[#count],
      'reflect(new BadEqualityHash()).type.declarations[#count]':
          reflect(new BadEqualityHash()).type.declarations[#count]
    },
    {
      'reflectType(Predicate)': reflectType(Predicate),
      'thisLibrary.declarations[#somePredicate].type':
          (thisLibrary.declarations[#somePredicate] as VariableMirror).type
    },
    {
      'reflectType(Predicate).referent':
          (reflectType(Predicate) as TypedefMirror).referent,
      'thisLibrary.declarations[#somePredicate].type.referent':
          ((thisLibrary.declarations[#somePredicate] as VariableMirror).type
                  as TypedefMirror)
              .referent
    },
    {
      'reflectClass(A).typeVariables.single':
          reflectClass(A).typeVariables.single,
      'reflect(new A<int>()).type.originalDeclaration.typeVariables.single':
          reflect(new A<int>()).type.originalDeclaration.typeVariables.single
    },
    {'currentMirrorSystem()': currentMirrorSystem()},
    {'currentMirrorSystem().isolate': currentMirrorSystem().isolate},
    {
      'thisLibrary': thisLibrary,
      'reflectClass(A).owner': reflectClass(A).owner,
      'reflectClass(B).owner': reflectClass(B).owner,
      'reflect(new A()).type.owner': reflect(new A()).type.owner,
      'reflect(new B()).type.owner': reflect(new B()).type.owner
    },
  ]);
}
