// 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: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 '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<LanguageVersionForUri> 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 LanguageVersionForUri(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 LanguageVersionForUri(major, minor);
    }

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

class LanguageVersionForUri {
  final int major;
  final int minor;

  LanguageVersionForUri(this.major, this.minor);
}
