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

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);
}
