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

// @dart = 2.9

// 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
    },
  ]);
}
