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

import 'dart:async';
import "package:async_helper/async_helper.dart";
import 'compiler_helper.dart';
import "package:expect/expect.dart";

Future compile(String source) {
  Uri uri = Uri.parse('test:code');
  var compiler =
      compilerFor(source, uri, analyzeOnly: true, enableTypeAssertions: true);
  compiler.diagnosticHandler = createHandler(compiler, source);
  return compiler.run(uri).then((_) {
    return compiler;
  });
}

Future test(String source, {var errors, var warnings}) async{
  if (errors == null) errors = [];
  if (errors is! List) errors = [errors];
  if (warnings == null) warnings = [];
  if (warnings is! List) warnings = [warnings];
  var compiler = await compile(source);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.equals(!errors.isEmpty, compiler.compilationFailed);
  Expect.equals(errors.length, collector.errors.length,
                'unexpected error count: ${collector.errors.length} '
                'expected ${errors.length}');
  Expect.equals(warnings.length, collector.warnings.length,
                'unexpected warning count: ${collector.warnings.length} '
                'expected ${warnings.length}');

  for (int i = 0 ; i < errors.length ; i++) {
    Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
  }
  for (int i = 0 ; i < warnings.length ; i++) {
    Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind);
  }
}

Future test1() async {
  var compiler = await compile(r"""
class A<T extends T> {}

void main() {
  new A();
}
""");
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isFalse(compiler.compilationFailed);
  Expect.isTrue(collector.errors.isEmpty,
                'unexpected errors: ${collector.errors}');
  Expect.equals(1, collector.warnings.length,
                'expected exactly one warning, but got ${collector.warnings}');

  print(collector.warnings.elementAt(0));
  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(0).message.kind);
  Expect.equals("T",
      collector.warnings.elementAt(0).message.arguments['typeVariableName']);
}

Future test2() async {
  var compiler = await compile(r"""
class B<T extends S, S extends T> {}

void main() {
  new B();
}
""");
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isFalse(compiler.compilationFailed);
  print(collector.errors);
  Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
  Expect.equals(2, collector.warnings.length,
                'expected exactly two errors, but got ${collector.warnings}');

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(0).message.kind);
  Expect.equals("T",
      collector.warnings.elementAt(0).message.arguments['typeVariableName']);

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(1).message.kind);
  Expect.equals("S",
      collector.warnings.elementAt(1).message.arguments['typeVariableName']);
}

Future test3() async {
  var compiler = await compile(r"""
class C<T extends S, S extends U, U extends T> {}

void main() {
  new C();
}
""");
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isFalse(compiler.compilationFailed);
  print(collector.errors);
  Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
  Expect.equals(3, collector.warnings.length,
                'expected exactly one error, but got ${collector.warnings}');

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(0).message.kind);
  Expect.equals("T",
      collector.warnings.elementAt(0).message.arguments['typeVariableName']);

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(1).message.kind);
  Expect.equals("S",
      collector.warnings.elementAt(1).message.arguments['typeVariableName']);

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(2).message.kind);
  Expect.equals("U",
      collector.warnings.elementAt(2).message.arguments['typeVariableName']);
}

Future test4() async {
  var compiler = await compile(r"""
class D<T extends S, S extends U, U extends S> {}

void main() {
  new D();
}
""");
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isFalse(compiler.compilationFailed);
  print(collector.errors);
  Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
  Expect.equals(2, collector.warnings.length,
                'expected exactly one error, but got ${collector.warnings}');

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(0).message.kind);
  Expect.equals("S",
      collector.warnings.elementAt(0).message.arguments['typeVariableName']);

  Expect.equals(MessageKind.CYCLIC_TYPE_VARIABLE,
                collector.warnings.elementAt(1).message.kind);
  Expect.equals("U",
      collector.warnings.elementAt(1).message.arguments['typeVariableName']);
}

Future test5() {
  return test(r"""
class A<T extends num> {}

void main() {
  new A();
  new A<num>();
  new A<dynamic>();
  new A<int>();
  new A<double>();
}
""");
}

Future test6() {
  return test(r"""
class A<T extends num> {}

void main() {
  new A<String>();
}
""", warnings: MessageKind.INVALID_TYPE_VARIABLE_BOUND);
}

Future test7() {
  return test(r"""
class A<T extends num> {}
class B<T> extends A<T> {} // Warning produced here.

void main() {
  new B(); // No warning produced here.
  new B<String>(); // No warning produced here.
}
""", warnings: MessageKind.INVALID_TYPE_VARIABLE_BOUND);
}

Future test8() {
  return test(r"""
class B<T extends B<T>> {}
class C<T extends B<T>> extends B<T> {}
class D<T extends C<T>> extends C<T> {}
class E<T extends E<T>> extends D<T> {}
class F extends E<F> {}

void main() {
  new B();
  new B<dynamic>();
  new B<F>();
  new B<B<F>>();
  new C();
  new C<dynamic>();
  new C<B<F>>();
  new D();
  new D<dynamic>();
  new D<C<F>>();
  new E();
  new E<dynamic>();
  new E<E<F>>();
  new F();
}
""");
}

Future test9() {
  return test(r"""
class B<T extends B<T>> {}
class C<T extends B<T>> extends B<T> {}
class D<T extends C<T>> extends C<T> {}
class E<T extends E<T>> extends D<T> {}
class F extends E<F> {}

void main() {
  new D<B<F>>(); // Warning: B<F> is not a subtype of C<T>.
  new E<D<F>>(); // Warning: E<F> is not a subtype of E<T>.
}
""", warnings: [MessageKind.INVALID_TYPE_VARIABLE_BOUND,
                MessageKind.INVALID_TYPE_VARIABLE_BOUND]);
}

Future test10() {
  return test(r"""
class A {
  const A();
}
class Test<T extends A> {
  final T x = const A();
  const Test();
}
main() {
  print(const Test<A>());
}
""");
}

// TODO(het): The error is reported twice because both the Dart and JS constant
// compilers are run on the const constructor, investigate why.
Future test11() {
  return test(r"""
class A {
  const A();
}
class B extends A {
  const B();
}
class Test<T extends A> {
  final T x = const A();
  const Test();
}
main() {
  print(const Test<B>());
}
""", errors: [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
}

main() {
  asyncTest(() async {
    await test1();
    await test2();
    await test3();
    await test4();
    await test5();
    await test6();
    await test7();
    await test8();
    await test9();
    await test10();
    await test11();
  });
}
