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

import 'dart:async';
import 'dart:io';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/type_environment.dart';
import 'package:kernel/src/printer.dart';
import 'package:kernel/target/targets.dart';
import 'package:test/test.dart';

import 'package:dev_compiler/src/kernel/command.dart';
import 'package:dev_compiler/src/kernel/nullable_inference.dart';
import 'package:dev_compiler/src/kernel/js_typerep.dart';
import 'package:dev_compiler/src/kernel/target.dart';

const AstTextStrategy astTextStrategy = AstTextStrategy(
    includeLibraryNamesInTypes: true,
    includeLibraryNamesInMembers: true,
    useMultiline: false);

void main() {
  test('empty main', () async {
    await expectNotNull('main() {}', '');
  });

  group('literal', () {
    test('null', () async {
      await expectNotNull('main() { print(null); }', '');
    });
    test('bool', () async {
      await expectNotNull('main() { print(false); }', 'false');
    });
    test('int', () async {
      await expectNotNull('main() { print(42); }', '42');
    });
    test('double', () async {
      await expectNotNull('main() { print(123.0); }', '123.0');
    });
    test('String', () async {
      await expectNotNull('main() { print("hi"); }', '"hi"');
    });
    test('List', () async {
      await expectNotNull(
          'main() { print([42, null]); }', '<dart.core::int*>[42, null], 42');
    });
    test('Map', () async {
      await expectNotNull('main() { print({"x": null}); }',
          '<dart.core::String*, dart.core::Null?>{"x": null}, "x"');
    });

    test('Symbol', () async {
      await expectNotNull('main() { print(#hi); }', '#hi');
    });

    test('Type', () async {
      await expectNotNull('main() { print(Object); }', 'dart.core::Object*');
    });
  });

  test('this', () async {
    await expectNotNull('class C { m() { return this; } }', 'this');
  });

  test('is', () async {
    await expectNotNull('main() { 42 is int; null is int; }',
        '42 is dart.core::int*, 42, null is dart.core::int*');
  });

  test('as', () async {
    await expectNotNull(
        'main() { 42 as int; null as int; }', '42 as dart.core::int*, 42');
  });

  test('constructor', () async {
    await expectNotNull(
        'library a; class C {} main() { new C(); }', 'new a::C()');
  });

  group('operator', () {
    test('==', () async {
      // This is not a correct non-null assumption when user-defined operators,
      // are present, see: https://github.com/dart-lang/sdk/issues/31854
      await expectAllNotNull('main() { 1 == 1; }');
    });
    test('!', () async {
      await expectAllNotNull('main() { !false; }');
    });
    test('!=', () async {
      await expectAllNotNull('main() { 1 != 2; }');
    });
    test('&&', () async {
      await expectAllNotNull('main() { true && true; }');
    });
    test('||', () async {
      await expectAllNotNull('main() { true || true; }');
    });
    test('? :', () async {
      await expectAllNotNull('main() { true ? true : false; }');
    });
  });

  test('bool', () async {
    await expectAllNotNull('main() { true.toString(); false.hashCode; }');
  });

  group('int', () {
    test('arithmetic', () async {
      await expectAllNotNull(
          'main() { -0; 1 + 2; 3 - 4; 5 * 6; 7 / 8; 9 % 10; 11 ~/ 12; }');
    });
    test('bitwise', () async {
      await expectAllNotNull(
          'main() { 1 & 2; 3 | 4; 5 ^ 6; ~7; 8 << 9; 10 >> 11; }');
    });
    test('comparison', () async {
      await expectAllNotNull('main() { 1 < 2; 3 > 4; 5 <= 6; 7 >= 8; }');
    });
    test('getters', () async {
      await expectAllNotNull(
          'main() { 1.isOdd; 1.isEven; 1.isNegative; 1.isNaN; 1.isInfinite; '
          '1.isFinite; 1.sign; 1.bitLength; 1.hashCode; }');
    });
    test('methods', () async {
      await expectAllNotNull(
          'main() { 1.compareTo(2); 1.remainder(2); 1.abs(); 1.toInt(); '
          '1.ceil(); 1.floor(); 1.truncate(); 1.round(); 1.ceilToDouble(); '
          '1.floorToDouble(); 1.truncateToDouble(); 1.roundToDouble(); '
          '1.toDouble(); 1.clamp(2, 2); 1.toStringAsFixed(2); '
          '1.toStringAsExponential(); 1.toStringAsPrecision(2); 1.toString(); '
          '1.toRadixString(2); 1.toUnsigned(2); 1.toSigned(2); 1.modPow(2, 2); '
          '1.modInverse(2); 1.gcd(2); }');
    });
  });

  group('double', () {
    test('arithmetic', () async {
      await expectAllNotNull(
          'main() { -0.0; 1.0 + 2.0; 3.0 - 4.0; 5.0 * 6.0; 7.0 / 8.0; '
          '9.0 % 10.0; 11.0 ~/ 12.0; }');
    });
    test('comparison', () async {
      await expectAllNotNull(
          'main() { 1.0 < 2.0; 3.0 > 4.0; 5.0 <= 6.0; 7.0 >= 8.0; }');
    });
    test('getters', () async {
      await expectAllNotNull(
          'main() { (1.0).isNegative; (1.0).isNaN; (1.0).isInfinite; '
          '(1.0).isFinite; (1.0).sign; (1.0).hashCode; }');
    });
    test('methods', () async {
      await expectAllNotNull(
          'main() { (1.0).compareTo(2.0); (1.0).remainder(2.0); (1.0).abs(); '
          '(1.0).toInt(); (1.0).ceil(); (1.0).floor(); (1.0).truncate(); '
          '(1.0).round(); (1.0).ceilToDouble(); (1.0).floorToDouble(); '
          '(1.0).truncateToDouble(); (1.0).roundToDouble(); (1.0).toDouble(); '
          '(1.0).clamp(2.0, 2.0); (1.0).toStringAsFixed(2); (1.0).toString(); '
          '(1.0).toStringAsExponential(); (1.0).toStringAsPrecision(2); }');
    });
  });

  group('num', () {
    test('arithmetic', () async {
      await expectAllNotNull(
          'main() { num n = 1; -n; n + n; n - n; n * n; n / n; n % n; n % n; '
          'n ~/ n; }');
    });
    test('comparison', () async {
      await expectAllNotNull(
          'main() { num n = 1; n < n; n > n; n <= n; n >= n; }');
    });
    test('getters', () async {
      await expectAllNotNull(
          'main() { num n = 1; n.isNegative; n.isNaN; n.isInfinite; '
          'n.isFinite; n.sign; n.hashCode; }');
    });
    test('methods', () async {
      await expectAllNotNull(
          'main() { num n = 1; n.compareTo(n); n.remainder(n); n.abs(); '
          'n.toInt(); n.ceil(); n.floor(); n.truncate(); '
          'n.round(); n.ceilToDouble(); n.floorToDouble(); '
          'n.truncateToDouble(); n.roundToDouble(); n.toDouble(); '
          'n.clamp(n, n); n.toStringAsFixed(n); n.toString(); '
          'n.toStringAsExponential(); n.toStringAsPrecision(n); }');
    });
  });

  group('String', () {
    test('concatenation', () async {
      await expectAllNotNull('main() { "1" "2"; }');
    });
    test('interpolation', () async {
      await expectAllNotNull('main() { "1${2}"; }');
    });
    test('getters', () async {
      await expectAllNotNull(
          'main() { "".codeUnits; "".hashCode; "".isEmpty; "".isNotEmpty; '
          '"".length; "".runes; }');
    });
    test('operators', () async {
      await expectAllNotNull('main() { "" + ""; "" * 2; "" == ""; "x"[0]; }');
    });
    test('methods', () async {
      await expectAllNotNull('''main() {
        String s = '';
        s.codeUnitAt(0);
        s.contains(s);
        s.endsWith(s);
        s.indexOf(s);
        s.lastIndexOf(s);
        s.padLeft(1);
        s.padRight(1);
        s.replaceAll(s, s);
        s.replaceAllMapped(s, (_) => s);
        s.replaceFirst(s, s);
        s.replaceFirstMapped(s, (_) => s);
        s.replaceRange(1, 2, s);
        s.split(s);
        s.splitMapJoin(s, onMatch: (_) => s, onNonMatch: (_) => s);
        s.startsWith(s);
        s.substring(1);
        s.toLowerCase();
        s.toUpperCase();
        s.trim();
        s.trimLeft();
        s.trimRight();

        // compareTo relies on the interface target being String.compareTo
        // except that method does not exist unless we insert too many
        // forwarding stubs.
        //
        // s.compareTo(s);

        s.toString();
        // Pattern methods (allMatches, matchAsPrefix) are not recognized.
      }''');
    });
  });

  test('identical', () async {
    await expectNotNull('main() { identical(null, null); }',
        'dart.core::identical(null, null)');
  });

  test('throw', () async {
    await expectNotNull('main() { print(throw null); }', 'throw null');
  });

  test('rethrow', () async {
    await expectNotNull('main() { try {} catch (e) { rethrow; } }', 'rethrow');
  });

  test('function expression', () async {
    await expectNotNull(
        'main() { () => null; f() {}; f; }', 'dart.core::Null? () => null, f');
  });

  test('cascades (kernel BlockExpression)', () async {
    // `null..toString()` evaluates to `null` so it is nullable.
    await expectNotNull('main() { null..toString(); }', '');
    await expectAllNotNull('main() { 1..toString(); }');
  });

  group('variable', () {
    test('declaration not-null', () async {
      await expectNotNull('main() { var x = 42; print(x); }', '42, x');
    });
    test('declaration null', () async {
      await expectNotNull('main() { var x = null; print(x); }', '');
    });
    test('declaration without initializer', () async {
      await expectNotNull('main() { var x; x = 1; print(x); }', 'x = 1, 1');
    });
    test('assignment non-null', () async {
      await expectNotNull(
          'main() { var x = 42; x = 1; print(x); }', '42, x = 1, 1, x');
    });
    test('assignment null', () async {
      await expectNotNull('main() { var x = 42; x = null; print(x); }', '42');
    });
    test('flow insensitive', () async {
      await expectNotNull('''main() {
        var x = 1;
        if (true) {
          print(x);
        } else {
          x = null;
          print(x);
        }
      }''', '1, true');
    });

    test('declaration from variable', () async {
      await expectNotNull('''main() {
        var x = 1;
        var y = x;
        print(y);
        x = null;
      }''', '1');
    });
    test('declaration from variable nested', () async {
      await expectNotNull('''main() {
        var x = 1;
        var y = (x = null) == null;
        print(x);
        print(y);
      }''', '1, (x = null).{dart.core::Object.==}(null), y');
    });
    test('declaration from variable transitive', () async {
      await expectNotNull('''main() {
        var x = 1;
        var y = x;
        var z = y;
        print(z);
        x = null;
      }''', '1');
    });
    test('declaration between variable transitive nested', () async {
      await expectNotNull('''main() {
        var x = 1;
        var y = 1;
        var z = y = x;
        print(z);
        x = null;
      }''', '1, 1');
    });

    test('for not-null', () async {
      await expectAllNotNull('''main() {
        for (var i = 0; i < 10; i++) {
          i;
        }
      }''');
    });
    test('for nullable', () async {
      await expectNotNull(
          '''main() {
        for (var i = 0; i < 10; i++) {
          if (i >= 10) i = null;
        }
      }''',
          // arithmetic operation results on `i` are themselves not null, even
          // though `i` is nullable.
          '0, i.{dart.core::num.<}(10), 10, i = i.{dart.core::num.+}(1), '
              'i.{dart.core::num.+}(1), 1, i.{dart.core::num.>=}(10), 10');
    });
    test('for-in', () async {
      await expectNotNull('''main() {
        for (var i in []) {
          print(i);
        }
      }''', '<dynamic>[]');
    });

    test('inner functions', () async {
      await expectNotNull('''main() {
        var y = 0;
        f(x) {
          var g = () => print('g');
          g();
          print(x);
          print(y);
          var z = 1;
          print(z);
        }
        f(42);
      }''', '0, void () => dart.core::print("g"), "g", g, y, 1, z, f, 42');
    });
    test('assignment to closure variable', () async {
      await expectNotNull('''main() {
        var y = 0;
        f(x) {
          y = x;
        }
        f(42);
        print(y);
      }''', '0, f, 42');
    });

    test('declaration visits initializer', () async {
      await expectAllNotNull('''main() {
        var x = () { var y = 1; return y; };
        x;
      }''');
    });
    test('assignment visits value', () async {
      await expectAllNotNull('''main() {
        var x = () => 42;
        x = () { var y = 1; return y; };
      }''');
    });
    test('assignment visits value with closure variable set', () async {
      await expectNotNull('''main() {
        var x = () => 42;
        var y = (() => x = null);
      }''', 'dart.core::int* () => 42, 42, dart.core::Null? () => x = null');
    });
    test('do not depend on unrelated variables', () async {
      await expectNotNull('''main() {
        var x;
        var y = identical(x, null);
        y; // this is still non-null even though `x` is nullable
      }''', 'dart.core::identical(x, null), y');
    });
    test('do not depend on unrelated variables updated later', () async {
      await expectNotNull('''main() {
        var x = 1;
        var y = identical(x, 1);
        x = null;
        y; // this is still non-null even though `x` is nullable
      }''', '1, dart.core::identical(x, 1), 1, y');
    });
  });
  group('functions parameters in SDK', () {
    setUp(() {
      // Using annotations here to test how the parameter is detected when
      // compiling functions from the SDK.
      // A regression test for: https://github.com/dart-lang/sdk/issues/37700
      useAnnotations = true;
    });
    tearDown(() {
      useAnnotations = false;
    });
    test('optional with default value', () async {
      await expectNotNull('''
        f(x, [y = 1]) { x; y; }
      ''', '1');
    });
    test('named with default value', () async {
      await expectNotNull('''
        f(x, {y = 1}) { x; y; }
      ''', '1');
    });
  });

  group('notNull', () {
    setUp(() {
      useAnnotations = true;
    });
    tearDown(() {
      useAnnotations = false;
    });
    var imports = "import 'package:meta/meta.dart';";
    group('(previously known kernel annotation bug)', () {
      test('variable without initializer', () async {
        await expectNotNull(
            '$imports main() { @notNull var x; print(x); }', 'x');
      });
      test('variable with initializer', () async {
        // TODO(jmesserly): this does not work in the Analyzer backend.
        await expectNotNull(
            '$imports main() { @notNull var x = null; print(x); }', 'x');
      });
      test('parameters', () async {
        await expectNotNull(
            '$imports f(@notNull x, [@notNull y, @notNull z = 42]) '
                '{ x; y; z; }',
            '42, x, y, z');
      });
      test('named parameters', () async {
        await expectNotNull(
            '$imports f({@notNull x, @notNull y: 42}) { x; y; }', '42, x, y');
      });
    });

    test('top-level field', () async {
      await expectNotNull(
          'library a; $imports @notNull int x; main() { x; }', 'a::x');
    });

    test('getter', () async {
      await expectNotNull(
          'library b; $imports @notNull get x => null; main() { x; }', 'b::x');
    });

    test('function', () async {
      await expectNotNull(
          'library a; $imports @notNull f() {} main() { f(); }', 'a::f()');
    });

    test('method', () async {
      await expectNotNull(
          'library b; $imports class C { @notNull m() {} } '
              'main() { var c = new C(); c.m(); }',
          'new b::C(), c.{b::C.m}(), c');
    });
  });
}

/// Given the Dart [code], expects the [expectedNotNull] kernel expression list
/// to be produced in the set of expressions that cannot be null by DDC's null
/// inference.
Future expectNotNull(String code, String expectedNotNull) async {
  var result = await kernelCompile(code);
  var collector = NotNullCollector(result.librariesFromDill);
  result.component.accept(collector);
  var actualNotNull = collector.notNullExpressions
      // ConstantExpressions print the table offset - we want to compare
      // against the underlying constant value instead.
      .map((e) {
        if (e is ConstantExpression) {
          var c = e.constant;
          if (c is DoubleConstant &&
              c.value.isFinite &&
              c.value.truncateToDouble() == c.value) {
            // Print integer values as integers
            return BigInt.from(c.value).toString();
          }
          return c.toText(astTextStrategy);
        }
        return e.toText(astTextStrategy);
      })
      // Filter out our own NotNull annotations.  The library prefix changes
      // per test, so just filter on the suffix.
      .where((s) => !s.endsWith('_NotNull{}'))
      .join(', ');
  expect(actualNotNull, equals(expectedNotNull));
}

/// Given the Dart [code], expects all the expressions inferred to be not-null.
Future expectAllNotNull(String code) async {
  var result = (await kernelCompile(code));
  result.component.accept(ExpectAllNotNull(result.librariesFromDill));
}

bool useAnnotations = false;
NullableInference inference;

class _TestRecursiveVisitor extends RecursiveVisitor<void> {
  final Set<Library> librariesFromDill;
  int _functionNesting = 0;
  TypeEnvironment _typeEnvironment;
  StatefulStaticTypeContext _staticTypeContext;

  _TestRecursiveVisitor(this.librariesFromDill);

  @override
  void visitComponent(Component node) {
    var coreTypes = CoreTypes(node);
    var hierarchy = ClassHierarchy(node, coreTypes);
    var jsTypeRep = JSTypeRep(
      fe.TypeSchemaEnvironment(coreTypes, hierarchy),
      hierarchy,
    );
    _typeEnvironment = jsTypeRep.types;
    _staticTypeContext = StatefulStaticTypeContext.stacked(_typeEnvironment);
    inference ??= NullableInference(jsTypeRep, _staticTypeContext);

    if (useAnnotations) {
      inference.allowNotNullDeclarations = useAnnotations;
      inference.allowPackageMetaAnnotations = useAnnotations;
    }
    super.visitComponent(node);
  }

  @override
  void visitLibrary(Library node) {
    _staticTypeContext.enterLibrary(node);
    if (librariesFromDill.contains(node) ||
        node.importUri.scheme == 'package' &&
            node.importUri.pathSegments[0] == 'meta') {
      return;
    }
    super.visitLibrary(node);
    _staticTypeContext.leaveLibrary(node);
  }

  @override
  void visitField(Field node) {
    _staticTypeContext.enterMember(node);
    super.visitField(node);
    _staticTypeContext.leaveMember(node);
  }

  @override
  void visitConstructor(Constructor node) {
    _staticTypeContext.enterMember(node);
    super.visitConstructor(node);
    _staticTypeContext.leaveMember(node);
  }

  @override
  void visitProcedure(Procedure node) {
    _staticTypeContext.enterMember(node);
    super.visitProcedure(node);
    _staticTypeContext.leaveMember(node);
  }

  @override
  void visitFunctionNode(FunctionNode node) {
    _functionNesting++;
    if (_functionNesting == 1) {
      inference.enterFunction(node);
    }
    super.visitFunctionNode(node);
    if (_functionNesting == 1) inference.exitFunction(node);
    _functionNesting--;
  }
}

class NotNullCollector extends _TestRecursiveVisitor {
  final notNullExpressions = <Expression>[];

  NotNullCollector(Set<Library> librariesFromDill) : super(librariesFromDill);

  @override
  void defaultExpression(Expression node) {
    if (!inference.isNullable(node)) {
      notNullExpressions.add(node);
    }
    super.defaultExpression(node);
  }
}

class ExpectAllNotNull extends _TestRecursiveVisitor {
  ExpectAllNotNull(Set<Library> librariesFromDill) : super(librariesFromDill);

  @override
  void defaultExpression(Expression node) {
    expect(inference.isNullable(node), false,
        reason: 'expression `$node` should be inferred as not-null');
    super.defaultExpression(node);
  }
}

fe.InitializedCompilerState _compilerState;
final _fileSystem = fe.MemoryFileSystem(Uri.file('/memory/'));

class CompileResult {
  final Component component;
  final Set<Library> librariesFromDill;

  CompileResult(this.component, this.librariesFromDill);
}

Future<CompileResult> kernelCompile(String code) async {
  var succeeded = true;
  void diagnosticMessageHandler(fe.DiagnosticMessage message) {
    if (message.severity == fe.Severity.error) {
      succeeded = false;
    }
    fe.printDiagnosticMessage(message, print);
  }

  var sdkUri = Uri.file('/memory/dart_sdk.dill');
  var sdkFile = _fileSystem.entityForUri(sdkUri);
  if (!await sdkFile.exists()) {
    sdkFile.writeAsBytesSync(
        File(defaultSdkSummaryPath(soundNullSafety: false)).readAsBytesSync());
  }
  var packagesUri = Uri.file('/memory/.packages');
  var packagesFile = _fileSystem.entityForUri(packagesUri);
  if (!await packagesFile.exists()) {
    packagesFile.writeAsStringSync('meta:/memory/meta/lib');
    _fileSystem
        .entityForUri(Uri.file('/memory/meta/lib/meta.dart'))
        .writeAsStringSync('''
class _NotNull { const _NotNull(); }
const notNull = const _NotNull();
class _NullCheck { const _NullCheck(); }
const nullCheck = const _NullCheck();
    ''');
  }

  var mainUri = Uri.file('/memory/test.dart');
  _fileSystem.entityForUri(mainUri).writeAsStringSync(code);
  var oldCompilerState = _compilerState;
  _compilerState = await fe.initializeCompiler(oldCompilerState, false, null,
      sdkUri, packagesUri, null, [], DevCompilerTarget(TargetFlags()),
      fileSystem: _fileSystem,
      experiments: const {},
      environmentDefines: const {},
      nnbdMode: fe.NnbdMode.Weak);
  if (!identical(oldCompilerState, _compilerState)) inference = null;
  var result =
      await fe.compile(_compilerState, [mainUri], diagnosticMessageHandler);
  expect(succeeded, true);

  var librariesFromDill = result.computeLibrariesFromDill();
  return CompileResult(result.component, librariesFromDill);
}
