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

library jsinterop.world_test;

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/elements/elements.dart' show Element, ClassElement;
import 'package:compiler/src/js_backend/js_backend.dart';
import 'package:compiler/src/world.dart';
import '../type_test_helper.dart';

void main() {
  asyncTest(() async {
    await testClasses();
  });
}

testClasses() async {
  test(String mainSource,
      {List<String> directlyInstantiated: const <String>[],
      List<String> abstractlyInstantiated: const <String>[],
      List<String> indirectlyInstantiated: const <String>[]}) async {
    TypeEnvironment env = await TypeEnvironment.create(
        r"""
@JS()
class A {
  get foo;

  external A(var foo);
}

@JS()
class B {
  get foo;

  external B(var foo);
}

@JS()
@anonymous
class C {
  final foo;

  external factory C({foo});
}

@JS()
@anonymous
class D {
  final foo;

  external factory D({foo});
}

class E {
  final foo;

  E(this.foo);
}

class F {
  final foo;

  F(this.foo);
}

newA() => new A(0);
newB() => new B(1);
newC() => new C(foo: 2);
newD() => new D(foo: 3);
newE() => new E(4);
newF() => new F(5);
""",
        mainSource: """
import 'package:js/js.dart';

$mainSource
""",
        useMockCompiler: false);
    Map<String, ClassElement> classEnvironment = <String, ClassElement>{};

    ClassElement registerClass(ClassElement cls) {
      classEnvironment[cls.name] = cls;
      return cls;
    }

    ClosedWorld world = env.closedWorld;
    JavaScriptBackend backend = env.compiler.backend;
    ClassElement Object_ =
        registerClass(env.compiler.commonElements.objectClass);
    ClassElement Interceptor =
        registerClass(backend.helpers.jsInterceptorClass);
    ClassElement JavaScriptObject =
        registerClass(backend.helpers.jsJavaScriptObjectClass);
    ClassElement A = registerClass(env.getElement('A'));
    ClassElement B = registerClass(env.getElement('B'));
    ClassElement C = registerClass(env.getElement('C'));
    ClassElement D = registerClass(env.getElement('D'));
    ClassElement E = registerClass(env.getElement('E'));
    ClassElement F = registerClass(env.getElement('F'));

    Expect.equals(Interceptor.superclass, Object_);
    Expect.equals(JavaScriptObject.superclass, Interceptor);

    Expect.equals(A.superclass, JavaScriptObject);
    Expect.equals(B.superclass, JavaScriptObject);
    Expect.equals(C.superclass, JavaScriptObject);
    Expect.equals(D.superclass, JavaScriptObject);
    Expect.equals(E.superclass, Object_);
    Expect.equals(F.superclass, Object_);

    for (String name in classEnvironment.keys) {
      ClassElement cls = classEnvironment[name];
      bool isInstantiated = false;
      if (directlyInstantiated.contains(name)) {
        isInstantiated = true;
        Expect.isTrue(
            world.isDirectlyInstantiated(cls),
            "Expected $name to be directly instantiated in `${mainSource}`:"
            "\n${world.dump(cls)}");
      }
      if (abstractlyInstantiated.contains(name)) {
        isInstantiated = true;
        Expect.isTrue(
            world.isAbstractlyInstantiated(cls),
            "Expected $name to be abstractly instantiated in `${mainSource}`:"
            "\n${world.dump(cls)}");
      }
      if (indirectlyInstantiated.contains(name)) {
        isInstantiated = true;
        Expect.isTrue(
            world.isIndirectlyInstantiated(cls),
            "Expected $name to be indirectly instantiated in `${mainSource}`:"
            "\n${world.dump(cls)}");
      }
      if (!isInstantiated && (name != 'Object' && name != 'Interceptor')) {
        Expect.isFalse(
            world.isInstantiated(cls),
            "Expected $name to be uninstantiated in `${mainSource}`:"
            "\n${world.dump(cls)}");
      }
    }
  }

  await test('main() {}');

  await test('main() => newA();',
      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);

  await test('main() => newB();',
      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);

  await test('main() => newC();',
      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);

  await test('main() => newD();',
      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);

  await test('main() => newE();', directlyInstantiated: ['E']);

  await test('main() => newF();', directlyInstantiated: ['F']);

  await test('main() => [newD(), newE()];',
      directlyInstantiated: ['E'],
      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
}
