// Copyright (c) 2017, 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 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:front_end/src/fasta/util/bytes_sink.dart' show BytesSink;
import 'package:front_end/src/fasta/fasta_codes.dart';
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
import 'package:kernel/kernel.dart'
    show CanonicalName, Library, Program, loadProgramFromBytes;
import 'package:package_config/packages.dart' show Packages;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

main() {
  CompilerContext.runWithDefaultOptions((_) {
    defineReflectiveSuite(() {
      defineReflectiveTests(ProcessedOptionsTest);
    });
  });
}

@reflectiveTest
class ProcessedOptionsTest {
  MemoryFileSystem fileSystem =
      new MemoryFileSystem(Uri.parse('org-dartlang-test:///'));

  Program _mockOutline;

  Program get mockSummary => _mockOutline ??= new Program(
      libraries: [new Library(Uri.parse('org-dartlang-test:///a/b.dart'))]);

  test_compileSdk_false() {
    for (var value in [false, true]) {
      var raw = new CompilerOptions()..compileSdk = value;
      var processed = new ProcessedOptions(raw);
      expect(processed.compileSdk, value);
    }
  }

  test_sdk_summary_inferred() {
    // The sdk-summary is inferred by default form sdk-root, when compile-sdk is
    // false
    var raw = new CompilerOptions()
      ..sdkRoot = Uri.parse('org-dartlang-test:///sdk/dir/')
      ..compileSdk = false;
    expect(new ProcessedOptions(raw).sdkSummary,
        Uri.parse('org-dartlang-test:///sdk/dir/vm_platform.dill'));

    // But it is left null when compile-sdk is true
    raw = new CompilerOptions()
      ..sdkRoot = Uri.parse('org-dartlang-test:///sdk/dir/')
      ..compileSdk = true;
    expect(new ProcessedOptions(raw).sdkSummary, null);
  }

  test_fileSystem_noBazelRoots() {
    // When no bazel roots are specified, the filesystem should be passed
    // through unmodified.
    var raw = new CompilerOptions()..fileSystem = fileSystem;
    var processed = new ProcessedOptions(raw);
    expect(processed.fileSystem, same(fileSystem));
  }

  test_getSdkSummaryBytes_summaryLocationProvided() async {
    var uri = Uri.parse('org-dartlang-test:///sdkSummary');

    writeMockSummaryTo(uri);

    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..sdkSummary = uri;
    var processed = new ProcessedOptions(raw);

    var bytes = await processed.loadSdkSummaryBytes();
    expect(bytes, isNotEmpty);

    var sdkSummary = loadProgramFromBytes(bytes);
    expect(sdkSummary.libraries.single.importUri,
        mockSummary.libraries.single.importUri);
  }

  test_getSdkSummary_summaryLocationProvided() async {
    var uri = Uri.parse('org-dartlang-test:///sdkSummary');
    writeMockSummaryTo(uri);
    checkMockSummary(new CompilerOptions()
      ..fileSystem = fileSystem
      ..sdkSummary = uri);
  }

  void writeMockSummaryTo(Uri uri) {
    var sink = new BytesSink();
    new BinaryPrinter(sink).writeProgramFile(mockSummary);
    fileSystem.entityForUri(uri).writeAsBytesSync(sink.builder.takeBytes());
  }

  Future<Null> checkMockSummary(CompilerOptions raw) async {
    var processed = new ProcessedOptions(raw);
    var sdkSummary = await processed.loadSdkSummary(new CanonicalName.root());
    expect(sdkSummary.libraries.single.importUri,
        mockSummary.libraries.single.importUri);
  }

  test_getUriTranslator_explicitLibrariesSpec() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///libraries.json'))
        .writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
    var raw = new CompilerOptions()
      ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
      ..fileSystem = fileSystem
      ..librariesSpecificationUri =
          Uri.parse('org-dartlang-test:///libraries.json');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    expect(uriTranslator.dartLibraries.libraryInfoFor('foo').uri.path,
        '/bar.dart');
  }

  test_getUriTranslator_inferredLibrariesSpec() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('');
    fileSystem
        .entityForUri(
            Uri.parse('org-dartlang-test:///mysdk/lib/libraries.json'))
        .writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
      ..compileSdk = true
      ..sdkRoot = Uri.parse('org-dartlang-test:///mysdk/');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    expect(uriTranslator.dartLibraries.libraryInfoFor('foo').uri.path,
        '/mysdk/lib/bar.dart');
  }

  test_getUriTranslator_notInferredLibrariesSpec() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('');
    fileSystem
        .entityForUri(
            Uri.parse('org-dartlang-test:///mysdk/lib/libraries.json'))
        .writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri = Uri.parse('org-dartlang-test:///.packages')
      ..compileSdk = false // libraries.json is only inferred if true
      ..sdkRoot = Uri.parse('org-dartlang-test:///mysdk/');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    expect(uriTranslator.dartLibraries.libraryInfoFor('foo'), isNull);
  }

  checkPackageExpansion(
      String packageName, String packageDir, Packages packages) {
    var input = Uri.parse('package:$packageName/a.dart');
    var expected = Uri.parse('org-dartlang-test:///$packageDir/a.dart');
    expect(packages.resolve(input), expected);
  }

  test_getUriTranslator_explicitPackagesFile() async {
    // This .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    // This one should be used.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///explicit.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.packages');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion('foo', 'baz', uriTranslator.packages);
  }

  test_getUriTranslator_explicitPackagesFile_withBaseLocation() async {
    // This .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    // This one should be used.
    fileSystem
        .entityForUri(
            Uri.parse('org-dartlang-test:///base/location/explicit.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri =
          Uri.parse('org-dartlang-test:///base/location/explicit.packages');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages);
  }

  test_getUriTranslator_implicitPackagesFile_ambiguous() async {
    // This .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    // This one should be used.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///explicit.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri = Uri.parse('org-dartlang-test:///explicit.packages');
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion('foo', 'baz', uriTranslator.packages);
  }

  test_getUriTranslator_implicitPackagesFile_nextToScript() async {
    // Create the base directory.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
        .createDirectory();
    // Packages directory should be ignored (.packages file takes precedence).
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/packages/'))
        .createDirectory();
    // This .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    // This one should be used.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()..fileSystem = fileSystem;
    var processed = new ProcessedOptions(raw, false,
        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages);
  }

  test_getUriTranslator_implicitPackagesFile_searchAbove() async {
    // Create the base directory.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
        .createDirectory();
    // This .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    // This one should be used.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()..fileSystem = fileSystem;
    var processed = new ProcessedOptions(raw, false,
        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion('foo', 'base/baz', uriTranslator.packages);
  }

  test_getUriTranslator_implicitPackagesFile_packagesDirectory() async {
    // Create the base directory.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
        .createDirectory();
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/packages/'))
        .createDirectory();

    // Both of these .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
        .writeAsStringSync('foo:baz\n');
    var raw = new CompilerOptions()..fileSystem = fileSystem;
    var processed = new ProcessedOptions(raw, false,
        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
    var uriTranslator = await processed.getUriTranslator();
    checkPackageExpansion(
        'foo', 'base/location/packages/foo', uriTranslator.packages);
  }

  test_getUriTranslator_implicitPackagesFile_noPackages() async {
    // Create the base directory.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///base/location/'))
        .createDirectory();
    var errors = [];
    // .packages file should be ignored.
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var processed = new ProcessedOptions(raw, false,
        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
    var uriTranslator = await processed.getUriTranslator();
    expect(errors, isEmpty);
    expect(uriTranslator.packages.asMap(), isEmpty);
  }

  test_getUriTranslator_noPackages() async {
    var errors = [];
    // .packages file should be ignored.
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///.packages'))
        .writeAsStringSync('foo:bar\n');
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..packagesFileUri = new Uri()
      ..onError = (e) => errors.add(e);
    var processed = new ProcessedOptions(raw);
    var uriTranslator = await processed.getUriTranslator();
    expect(uriTranslator.packages.asMap(), isEmpty);
    expect(errors.single.message,
        startsWith(_stringPrefixOf(templateCannotReadPackagesFile)));
  }

  test_validateOptions_noInputs() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');
    var errors = [];
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw);
    var result = await options.validateOptions();
    expect(errors.single.message, messageMissingInput.message);
    expect(result, isFalse);
  }

  test_validateOptions_input_doesnt_exist() async {
    var errors = [];
    var raw = new CompilerOptions()
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    var result = await options.validateOptions();
    expect(errors.single.message,
        startsWith(_stringPrefixOf(templateInputFileNotFound)));
    expect(result, isFalse);
  }

  test_validateOptions_root_exists() async {
    var sdkRoot = Uri.parse('org-dartlang-test:///sdk/root/');
    fileSystem
        // Note: this test is a bit hackish because the memory file system
        // doesn't have the notion of directories.
        .entityForUri(sdkRoot)
        .writeAsStringSync('\n');
    fileSystem
        .entityForUri(sdkRoot.resolve('vm_platform.dill'))
        .writeAsStringSync('\n');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');

    var errors = [];
    var raw = new CompilerOptions()
      ..sdkRoot = sdkRoot
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    var result = await options.validateOptions();
    // Note: we check this first so test failures show the cause directly.
    expect(errors, isEmpty);
    expect(result, isTrue);
  }

  test_validateOptions_root_doesnt_exists() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');
    var sdkRoot = Uri.parse('org-dartlang-test:///sdk/root');
    var errors = [];
    var raw = new CompilerOptions()
      ..sdkRoot = sdkRoot
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    expect(await options.validateOptions(), isFalse);
    expect(errors.first.message,
        startsWith(_stringPrefixOf(templateSdkRootNotFound)));
  }

  test_validateOptions_summary_exists() async {
    var sdkSummary = Uri.parse('org-dartlang-test:///sdk/root/outline.dill');
    fileSystem.entityForUri(sdkSummary).writeAsStringSync('\n');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');

    var errors = [];
    var raw = new CompilerOptions()
      ..sdkSummary = sdkSummary
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    var result = await options.validateOptions();
    expect(errors, isEmpty);
    expect(result, isTrue);
  }

  test_validateOptions_summary_doesnt_exists() async {
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');
    var sdkSummary = Uri.parse('org-dartlang-test:///sdk/root/outline.dill');
    var errors = [];
    var raw = new CompilerOptions()
      ..sdkSummary = sdkSummary
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    expect(await options.validateOptions(), isFalse);
    expect(errors.single.message,
        startsWith(_stringPrefixOf(templateSdkSummaryNotFound)));
  }

  test_validateOptions_inferred_summary_exists() async {
    var sdkRoot = Uri.parse('org-dartlang-test:///sdk/root/');
    var sdkSummary =
        Uri.parse('org-dartlang-test:///sdk/root/vm_platform.dill');
    fileSystem.entityForUri(sdkRoot).writeAsStringSync('\n');
    fileSystem.entityForUri(sdkSummary).writeAsStringSync('\n');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');

    var errors = [];
    var raw = new CompilerOptions()
      ..sdkRoot = sdkRoot
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    var result = await options.validateOptions();
    expect(errors, isEmpty);
    expect(result, isTrue);
  }

  test_validateOptions_inferred_summary_doesnt_exists() async {
    var sdkRoot = Uri.parse('org-dartlang-test:///sdk/root/');
    var sdkSummary = Uri.parse('org-dartlang-test:///sdk/root/outline.dill');
    fileSystem.entityForUri(sdkRoot).writeAsStringSync('\n');
    fileSystem
        .entityForUri(Uri.parse('org-dartlang-test:///foo.dart'))
        .writeAsStringSync('main(){}\n');
    var errors = [];
    var raw = new CompilerOptions()
      ..sdkSummary = sdkSummary
      ..fileSystem = fileSystem
      ..onError = (e) => errors.add(e);
    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
    expect(await options.validateOptions(), isFalse);
    expect(errors.single.message,
        startsWith(_stringPrefixOf(templateSdkSummaryNotFound)));
  }

  /// Returns the longest prefix of the text in a message template that doesn't
  /// mention a template argument.
  _stringPrefixOf(Template template) {
    var messageTemplate = template.messageTemplate;
    var index = messageTemplate.indexOf('#');
    var prefix = messageTemplate.substring(0, index - 1);

    // Check that the prefix is not empty and that it contains more than one
    // word.
    expect(prefix.length > 0, isTrue);
    expect(prefix.contains(' '), isTrue);
    return prefix;
  }
}
