// 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/uri_translator.dart' show UriTranslator;

import 'compiler_options.dart' show CompilerOptions;

import 'experimental_flags.dart' show ExperimentalFlag;
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<VersionAndPackageUri> 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;
    late final int currentSdkVersionMajor;
    late final int currentSdkVersionMinor;
    // ignore: unnecessary_null_comparison
    if (currentSdkVersion != null) {
      List<String> dotSeparatedParts = currentSdkVersion.split(".");
      if (dotSeparatedParts.length >= 2) {
        currentSdkVersionMajor = int.parse(dotSeparatedParts[0]);
        currentSdkVersionMinor = int.parse(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.isScheme("package")) {
      fileUri = uriTranslator.translate(uri);
      package = uriTranslator.getPackage(uri);
    } else {
      fileUri = uri;
      package = uriTranslator.packages.packageOf(uri);
    }
    Uri packageUri = uri;
    if (!packageUri.isScheme('dart') &&
        !packageUri.isScheme('package') &&
        package != null &&
        // ignore: unnecessary_null_comparison
        package.name != null) {
      packageUri = new Uri(scheme: 'package', path: package.name);
    }

    // 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 VersionAndPackageUri(new Version(major!, minor!), packageUri);
    }

    // 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 VersionAndPackageUri(new Version(major!, minor!), packageUri);
    }

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

/// 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.
  VersionAndPackageUri versionAndLibraryUri =
      await languageVersionForUri(uri, options);
  return !options.isExperimentEnabledInLibraryByVersion(
      ExperimentalFlag.nonNullable,
      versionAndLibraryUri.packageUri,
      versionAndLibraryUri.version);
}

class VersionAndPackageUri {
  final Version version;
  final Uri packageUri;

  VersionAndPackageUri(this.version, this.packageUri);
}
