// 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 = mockCompilerFor(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();
  });
}
