// Copyright (c) 2020, 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 '../native_testing.dart';
import 'null_assertions_test_lib.dart';

// Implementations of `NativeInterface` and `JSInterface` in a folder that is
// part of the allowlist for the `--native-null-assertions` flag. This file is
// treated as a web library, and therefore native members and `JS()` invocations
// should be checked.

@Native("AAA")
class AAA implements NativeInterface {
  int get size native;
  String get name native;
  String? get optName native;
  int method1() native;
  String method2() native;
  String? optMethod() native;
}

@Native('CCC')
class CCC implements JSInterface {
  String get name => JS('String', '#.name', this);
  String? get optName => JS('String|Null', '#.optName', this);
}

/// Returns an 'AAA' object that satisfies the interface.
AAA makeA() native;

/// Returns an 'AAA' object where each method breaks the interface's contract.
AAA makeAX() native;

/// Returns a 'CCC' object that satisfies the interface using `JS()`
/// invocations.
CCC makeC() native;

/// Returns a 'CCC' object where each method breaks the interface's contract.
CCC makeCX() native;

// The 'AAA' version of the code is passed only objects of a single native
// class, so the native method can be inlined (which happens in the optimizer).
// This tests that the null-check exists in the 'inlined' code.

@pragma('dart2js:noInline')
String describeAAA(AAA o) {
  return '${o.name} ${o.method2()} ${o.size} ${o.method1()}';
}

@pragma('dart2js:noInline')
String describeOptAAA(AAA o) {
  return '${o.optName} ${o.optMethod()}';
}

void testNativeNullAssertions(bool flagEnabled) {
  nativeTesting();
  setup();
  AAA a = makeA();
  BBB b = BBB();

  Expect.equals(expectedA, describeNativeInterface(a));
  Expect.equals(expectedB, describeNativeInterface(b));

  Expect.equals(expectedA, describeAAA(a));

  AAA x = makeAX(); // This object returns `null`!
  // Since native members are in a web library, this should throw if null checks
  // are enabled.
  var checkExpectation = flagEnabled ? Expect.throws : (f) => f();
  checkExpectation(() => describeNativeInterface(x));
  checkExpectation(() => describeAAA(x));

  checkExpectation(() => x.name);
  checkExpectation(() => x.size);
  checkExpectation(() => x.method1());
  checkExpectation(() => x.method2());

  // Now test that a nullable return type does not have a check.
  Expect.equals(expectedOptA, describeOptNativeInterface(a));
  Expect.equals(expectedOptB, describeOptNativeInterface(b));
  Expect.equals(expectedOptX, describeOptNativeInterface(x));

  Expect.equals(expectedOptA, describeOptAAA(a));
  Expect.equals(expectedOptX, describeOptAAA(x));
}

void testJSInvocationNullAssertions(bool flagEnabled) {
  nativeTesting();
  setup();

  CCC c = makeC();
  CCC cx = makeCX();

  Expect.equals(expectedC, describeJSInterface(c));

  // Since invocations are in a web library, this should throw if null checks
  // are enabled.
  var checkExpectation = flagEnabled ? Expect.throws : (f) => f();
  checkExpectation(() => describeJSInterface(cx));

  // Test that invocations with a nullable static type do not have checks.
  Expect.equals(expectedOptC, describeOptJSInterface(c));
  Expect.equals(expectedOptCX, describeOptJSInterface(cx));
}
