// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:file/file.dart';
import 'package:package_config/package_config.dart';

final RegExp _languageVersion = RegExp(r'\/\/\s*@dart\s*=\s*([0-9])\.([0-9]+)');
final RegExp _declarationEnd = RegExp('(import)|(library)|(part)');
const String _blockCommentStart = '/*';
const String _blockCommentEnd = '*/';

/// The first language version where null safety was available by default.
final LanguageVersion nullSafeVersion = LanguageVersion(2, 12);

/// Attempts to read the language version of a dart [file].
///
/// If this is not present, falls back to the language version defined in
/// [package]. If [package] is not provided and there is no
/// language version header, returns 2.12. This does not specifically check
/// for language declarations other than library, part, or import.
///
/// The specification for the language version tag is defined at:
/// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
LanguageVersion determineLanguageVersion(File file, Package package) {
  int blockCommentDepth = 0;
  for (final String line in file.readAsLinesSync()) {
    final String trimmedLine = line.trim();
    if (trimmedLine.isEmpty) {
      continue;
    }
    // Check for the start or end of a block comment. Within a block
    // comment, all language version declarations are ignored. Block
    // comments can be nested, and the start or end may occur on
    // the same line. This does not handle the case of invalid
    // block comment combinations like `*/ /*` since that will cause
    // a compilation error anyway.
    bool sawBlockComment = false;
    final int startMatches = _blockCommentStart.allMatches(trimmedLine).length;
    final int endMatches = _blockCommentEnd.allMatches(trimmedLine).length;
    if (startMatches > 0) {
      blockCommentDepth += startMatches;
      sawBlockComment = true;
    }
    if (endMatches > 0) {
      blockCommentDepth -= endMatches;
      sawBlockComment = true;
    }
    if (blockCommentDepth != 0 || sawBlockComment) {
      continue;
    }
    // Check for a match with the language version.
    final Match match = _languageVersion.matchAsPrefix(trimmedLine);
    if (match != null) {
      final String rawMajor = match.group(1);
      final String rawMinor = match.group(2);
      try {
        final int major = int.parse(rawMajor);
        final int minor = int.parse(rawMinor);
        return LanguageVersion(major, minor);
      } on FormatException {
        // Language comment was invalid in a way that the regexp did not
        // anticipate.
        break;
      }
    }

    // Check for a declaration which ends the search for a language
    // version.
    if (_declarationEnd.matchAsPrefix(trimmedLine) != null) {
      break;
    }
  }

  // If the language version cannot be found, use the package version.
  if (package != null) {
    return package.languageVersion;
  }
  // Default to 2.12
  return nullSafeVersion;
}
