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

// @dart = 2.9

@JS()
library js_typed_interop_type_test;

import 'dart:html';
import 'package:js/js.dart';
import 'package:expect/expect.dart';

@JS()
class A {
  var foo;

  external A(var foo);
}

@JS()
class B {
  var 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);
}

@pragma('dart2js:noInline')
testA(A o) {
  return o.foo;
}

@pragma('dart2js:noInline')
testB(B o) {
  return o.foo;
}

@pragma('dart2js:noInline')
testC(C o) {
  return o.foo;
}

@pragma('dart2js:noInline')
testD(D o) {
  return o.foo;
}

@pragma('dart2js:noInline')
testE(E o) {
  return o.foo;
}

@pragma('dart2js:noInline')
testF(F o) {
  return o.foo;
}

_injectJs() {
  document.body.append(new ScriptElement()
    ..type = 'text/javascript'
    ..innerHtml = r"""
function A(foo) {
  this.foo = foo;
}

function B(foo) {
  this.foo = foo;
}
""");
}

void expectValueOrTypeError(f(), value) {
  try {
    dynamic i = 0;
    // TODO(rnystrom): Revisit this now that checked mode is gone in 2.0.
    String s = i; // Test for checked mode.
    Expect.equals(f(), value);
  } on TypeError catch (error) {
    Expect.throwsTypeError(f);
  }
}

main() {
  _injectJs();

  dynamic a = new A(1);
  dynamic b = new B(2);
  dynamic c = new C(foo: 3);
  dynamic d = new D(foo: 4);
  dynamic e = new E(5);
  dynamic f = new F(6);

  Expect.equals(testA(a), 1);
  Expect.equals(testB(b), 2);
  Expect.equals(testA(b), 2);
  Expect.equals(testA(c), 3);
  Expect.equals(testA(d), 4);
  expectValueOrTypeError(() => testA(e), 5);
  expectValueOrTypeError(() => testA(f), 6);

  Expect.equals(testB(a), 1);
  Expect.equals(testB(b), 2);
  Expect.equals(testB(c), 3);
  Expect.equals(testB(d), 4);
  expectValueOrTypeError(() => testB(e), 5);
  expectValueOrTypeError(() => testB(f), 6);

  Expect.equals(testC(a), 1);
  Expect.equals(testC(b), 2);
  Expect.equals(testC(c), 3);
  Expect.equals(testC(d), 4);
  expectValueOrTypeError(() => testC(e), 5);
  expectValueOrTypeError(() => testC(f), 6);

  Expect.equals(testD(a), 1);
  Expect.equals(testD(b), 2);
  Expect.equals(testD(c), 3);
  Expect.equals(testD(d), 4);
  expectValueOrTypeError(() => testD(e), 5);
  expectValueOrTypeError(() => testD(f), 6);

  expectValueOrTypeError(() => testE(a), 1);
  expectValueOrTypeError(() => testE(b), 2);
  expectValueOrTypeError(() => testE(c), 3);
  expectValueOrTypeError(() => testE(d), 4);
  Expect.equals(testE(e), 5);
  expectValueOrTypeError(() => testE(f), 6);

  expectValueOrTypeError(() => testF(a), 1);
  expectValueOrTypeError(() => testF(b), 2);
  expectValueOrTypeError(() => testF(c), 3);
  expectValueOrTypeError(() => testF(d), 4);
  expectValueOrTypeError(() => testF(e), 5);
  Expect.equals(testF(f), 6);
}
