// 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 'dart:typed_data' show Uint8List;

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show LanguageVersionToken, Scanner, ScannerConfiguration, scan;

import 'package:kernel/ast.dart' show Version;
export 'package:kernel/ast.dart' show Version;

import 'package:package_config/package_config.dart'
    show InvalidLanguageVersion, Package;

import '../base/processed_options.dart' show ProcessedOptions;

import '../fasta/compiler_context.dart' show CompilerContext;

import '../fasta/source/source_library_builder.dart' show SourceLibraryBuilder;

import '../fasta/uri_translator.dart' show UriTranslator;

import 'compiler_options.dart' show CompilerOptions;

import 'experimental_flags.dart'
    show ExperimentalFlag, experimentReleasedVersion;
import 'file_system.dart' show FileSystem, FileSystemException;

/// Gets the language version for a specific URI.
///
/// Note that this returning some language version, doesn't mean there aren't
/// errors associated with the language version specified (e.g. that the file
/// specifies a language version that's too high).
///
/// The language version returned is valid though.
Future<Version> languageVersionForUri(Uri uri, CompilerOptions options) async {
  return await CompilerContext.runWithOptions(
      new ProcessedOptions(options: options, inputs: [uri]), (context) async {
    // Get largest valid version / default version.
    String currentSdkVersion = context.options.currentSdkVersion;
    bool good = false;
    int currentSdkVersionMajor;
    int currentSdkVersionMinor;
    if (currentSdkVersion != null) {
      List<String> dotSeparatedParts = currentSdkVersion.split(".");
      if (dotSeparatedParts.length >= 2) {
        currentSdkVersionMajor = int.tryParse(dotSeparatedParts[0]);
        currentSdkVersionMinor = int.tryParse(dotSeparatedParts[1]);
        good = true;
      }
    }
    if (!good) {
      throw new StateError("Unparsable sdk version given: $currentSdkVersion");
    }

    // Get file uri.
    UriTranslator uriTranslator = await context.options.getUriTranslator();
    Uri fileUri;
    Package package;
    if (uri.scheme == "package") {
      fileUri = uriTranslator.translate(uri);
      package = uriTranslator.getPackage(uri);
    } else {
      fileUri = uri;
      package = uriTranslator.packages.packageOf(uri);
    }

    // Check file content for @dart annotation.
    int major;
    int minor;
    if (fileUri != null) {
      List<int> rawBytes;
      try {
        FileSystem fileSystem = context.options.fileSystem;
        rawBytes = await fileSystem.entityForUri(fileUri).readAsBytes();
      } on FileSystemException catch (_) {
        rawBytes = null;
      }
      if (rawBytes != null) {
        Uint8List zeroTerminatedBytes = new Uint8List(rawBytes.length + 1);
        zeroTerminatedBytes.setRange(0, rawBytes.length, rawBytes);

        scan(zeroTerminatedBytes,
            includeComments: false,
            configuration: new ScannerConfiguration(), languageVersionChanged:
                (Scanner scanner, LanguageVersionToken version) {
          if (major != null || minor != null) return;
          major = version.major;
          minor = version.minor;
        });
      }
    }

    if (major != null && minor != null) {
      // Verify OK.
      if (major > currentSdkVersionMajor ||
          (major == currentSdkVersionMajor && minor > currentSdkVersionMinor)) {
        major = null;
        minor = null;
      }
    }
    if (major != null && minor != null) {
      // The file decided. Return result.
      return new Version(major, minor);
    }

    // Check package.
    if (package != null &&
        package.languageVersion != null &&
        package.languageVersion is! InvalidLanguageVersion) {
      major = package.languageVersion.major;
      minor = package.languageVersion.minor;
      if (major > currentSdkVersionMajor ||
          (major == currentSdkVersionMajor && minor > currentSdkVersionMinor)) {
        major = null;
        minor = null;
      }
    }
    if (major != null && minor != null) {
      // The package decided. Return result.
      return new Version(major, minor);
    }

    // Return default.
    return new Version(currentSdkVersionMajor, currentSdkVersionMinor);
  });
}

/// Returns `true` if the language version of [uri] does not support null
/// safety.
Future<bool> uriUsesLegacyLanguageVersion(
    Uri uri, CompilerOptions options) async {
  // This method is here in order to use the opt out hack here for test
  // sources.
  if (SourceLibraryBuilder.isOptOutTest(uri)) return true;
  Version uriVersion = await languageVersionForUri(uri, options);
  return (uriVersion < experimentReleasedVersion[ExperimentalFlag.nonNullable]);
}
