// Copyright (c) 2019, 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.md file.

import 'dart:io';

import 'package:expect/expect.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/api_prototype/kernel_generator.dart';
import 'package:front_end/src/api_prototype/language_version.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:kernel/ast.dart';

/// The version used in this test as the experiment release version.
const Version experimentReleaseVersion = const Version(2, 9);

/// The version used in this test as the experiment enabled version.
const Version experimentEnabledVersion = const Version(2, 10);

Future<void> main() async {
  print('--------------------------------------------------------------------');
  print('Test off-by-default with command-line flag');
  print('--------------------------------------------------------------------');
  await test(
      enableNonNullableByDefault: false,
      enableNonNullableExplicitly: true,
      // When the flag is off by default, the experiment release version should
      // be used as the opt-in criterion for all libraries.
      versionImpliesOptIn: experimentReleaseVersion,
      versionOptsInAllowed: experimentReleaseVersion);

  print('--------------------------------------------------------------------');
  print('Test on-by-default');
  print('--------------------------------------------------------------------');
  await test(
      enableNonNullableByDefault: true,
      enableNonNullableExplicitly: false,
      // When the flag is on by default, the experiment release version should
      // be used as the opt-in criterion only for libraries in allowed packages
      // and the experiment enabled version should be used as the opt-in
      // criterion for all other libraries.
      versionImpliesOptIn: experimentEnabledVersion,
      versionOptsInAllowed: experimentReleaseVersion);

  print('--------------------------------------------------------------------');
  print('Test on-by-default and explicitly with command-line flag');
  print('--------------------------------------------------------------------');
  await test(
      enableNonNullableByDefault: true,
      enableNonNullableExplicitly: true,
      // When the flag is on by default but the experiment is enabled explicitly
      // the experiment release version should be used as the opt-in criterion
      // for all libraries.
      versionImpliesOptIn: experimentReleaseVersion,
      versionOptsInAllowed: experimentReleaseVersion);
}

Future<void> test(
    {required bool enableNonNullableByDefault,
    required bool enableNonNullableExplicitly,
    required Version versionImpliesOptIn,
    required Version versionOptsInAllowed}) async {
  CompilerOptions options = new CompilerOptions();
  if (enableNonNullableByDefault) {
    // Pretend non-nullable is on by default.
    options.defaultExperimentFlagsForTesting = {
      ExperimentalFlag.nonNullable: true
    };
  } else {
    // Pretend non-nullable is off by default.
    options.defaultExperimentFlagsForTesting = {
      ExperimentalFlag.nonNullable: false
    };
  }
  if (enableNonNullableExplicitly) {
    // Enable non-nullable explicitly on the command-line.
    options..explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
  }

  Uri sdkSummary = computePlatformBinariesLocation(forceBuildDir: true)
      .resolve('vm_platform_strong.dill');
  options
    ..sdkSummary = sdkSummary
    // Pretend current version is 2.11
    ..currentSdkVersion = '2.11'
    ..allowedExperimentalFlagsForTesting = new AllowedExperimentalFlags(
        sdkDefaultExperiments:
            defaultAllowedExperimentalFlags.sdkDefaultExperiments,
        sdkLibraryExperiments:
            defaultAllowedExperimentalFlags.sdkLibraryExperiments,
        packageExperiments: {
          ...defaultAllowedExperimentalFlags.packageExperiments,
          'allowed_package': {ExperimentalFlag.nonNullable}
        })
    ..experimentReleasedVersionForTesting = const {
      // Pretend non-nullable is released in version 2.9.
      ExperimentalFlag.nonNullable: experimentReleaseVersion
    }
    ..experimentEnabledVersionForTesting = const {
      // Pretend non-nullable is enabled in version 2.10.
      ExperimentalFlag.nonNullable: experimentEnabledVersion
    };

  bool hadDiagnostic = false;
  options.onDiagnostic = (DiagnosticMessage message) {
    print(message.plainTextFormatted);
    hadDiagnostic = true;
  };

  Directory directory = new Directory.fromUri(
      Uri.base.resolve('pkg/front_end/test/enable_non_nullable/data/'));
  CompilerResult result = (await kernelForProgramInternal(
      directory.uri.resolve('main.dart'), options,
      retainDataForTesting: true))!;
  Expect.isFalse(
      hadDiagnostic, "Compilation had diagnostics (errors, warnings)!");
  for (Library library in result.component!.libraries) {
    if (!library.importUri.isScheme('dart')) {
      bool usesLegacy =
          await uriUsesLegacyLanguageVersion(library.fileUri, options);
      VersionAndPackageUri versionAndPackageUri =
          await languageVersionForUri(library.fileUri, options);
      bool isNonNullableByDefault = library.isNonNullableByDefault;
      print('${library.fileUri}:');
      print(' version=${versionAndPackageUri.version}');
      print(' (package) uri=${versionAndPackageUri.packageUri}');
      print(' isNonNullableByDefault=${isNonNullableByDefault}');
      print(' uriUsesLegacyLanguageVersion=${usesLegacy}');
      Expect.equals(library.languageVersion, versionAndPackageUri.version,
          "Language version mismatch for ${library.importUri}");
      Expect.equals(
          !usesLegacy,
          isNonNullableByDefault,
          "Unexpected null-safe state for ${library.importUri}:"
          " isNonNullableByDefault=$isNonNullableByDefault,"
          " uriUsesLegacyLanguageVersion=$usesLegacy. "
          "Computed version=${versionAndPackageUri.version},"
          " (package) uri=${versionAndPackageUri.packageUri}");
      Expect.isTrue(
          library.languageVersion < versionImpliesOptIn ||
              library.isNonNullableByDefault,
          "Expected library ${library.importUri} with version "
          "${library.languageVersion} to be opted in.");
      Expect.isTrue(
          !versionAndPackageUri.packageUri.isScheme('package') ||
              !versionAndPackageUri.packageUri.path
                  .startsWith('allowed_package') ||
              library.languageVersion < versionOptsInAllowed ||
              library.isNonNullableByDefault,
          "Expected allowed library ${library.importUri} with version "
          "${library.languageVersion} to be opted in.");
    }
  }
}
