// Copyright (c) 2019, 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 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/error/codes.dart';

/// Finds invalid, or misplaced language override comments.
class LanguageVersionOverrideVerifier {
  static final _overrideCommentLine = RegExp(r'^\s*//\s*@dart\s*=\s*\d+\.\d+');

  final ErrorReporter _errorReporter;

  LanguageVersionOverrideVerifier(this._errorReporter);

  void verify(CompilationUnit unit) {
    _verifyMisplaced(unit);

    Token beginToken = unit.beginToken;
    if (beginToken.type == TokenType.SCRIPT_TAG) {
      beginToken = beginToken.next;
    }
    Token commentToken = beginToken.precedingComments;
    while (commentToken != null) {
      if (_findLanguageVersionOverrideComment(commentToken)) {
        // A valid language version override was found. Do not search for any
        // later invalid language version comments.
        return;
      }
      commentToken = commentToken.next;
    }
  }

  /// Look for comments which look almost like a Dart language version override,
  /// according to the spec [1].
  ///
  /// The idea of a comment which looks "almost" like a language version
  /// override is a tricky dance. It is important that this function _not_
  /// falsely report comment lines as an "invalid language version override"
  /// when the user was likely not trying to override the language version. Here
  /// is the general algorithm for deciding what to report:
  ///
  /// * When a comment begins with "@dart" or "dart" (letters in any case),
  ///   followed by optional whitespace, followed by optional non-alphanumeric,
  ///   non-whitespace characters, followed by optional whitespace, followed by
  ///   an optional alphabetical character, followed by a digit, followed by the
  ///   end of the line or a non-alphabetical character, then the comment is
  ///   considered to be an attempt at a language version override comment
  ///   (with one exception, below).
  ///   * If the "@" character is missing before "dart", _and_ the
  ///     non-alphabetical characters are not present, the comment is too
  ///     different from a valid language version override comment, and is not
  ///     considered to be an attempt. Examples include: "/// dart2 is great."
  ///   * If the comment began with more than two slashes, report the comment.
  ///     For example: "/// dart = 2".
  ///   * If the "@" character is missing before "dart", report the comment.
  ///     Examples include: "// dart = 2.0", "// dart @ 2.0".
  ///   * If the letters, "dart", are not all lower case, report the comment.
  ///     For example: "// @Dart = 2".
  ///   * If the non-alphabetical characters are not present or are not the
  ///     single character "=", report the comment. Examples include:
  ///     "// @dart: 2", "// @dart > 2.0", "// @dart >= 2.0", "// @dart 2.0".
  ///   * If the optional alphabetical letter is present, report the comment.
  ///     For example: "// @dart = v2".
  ///   * If the digit is not immediately followed by a "." character, then
  ///     another digit, then optional whitespace, then the end of the line,
  ///     report the comment. Examples include: "// @dart = 2",
  ///     "// @dart = 2,0", "// @dart = 2.15", "// @dart = 2.2.2",
  ///     "// @dart = 2.2 or so".
  ///   * Otherwise, the comment is a valid language version override comment.
  /// * Otherwise, the comment is not considered to be an attempt at a language
  ///   version override comment. Nothing is reported. Examples include:
  ///   "/// dart", "/// dart is great", "// dartisans are great",
  ///   "// dart = java, basically".
  ///
  /// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
  bool _findLanguageVersionOverrideComment(Token commentToken) {
    String comment = commentToken.lexeme;
    int offset = commentToken.offset;
    int length = comment.length;
    int index = 0;

    // TODO(srawlins): Actual whitespace.
    bool isWhitespace(int character) => character == 0x09 || character == 0x20;

    bool isNumeric(int character) => character >= 0x30 && character <= 0x39;

    bool isAlphabetical(int character) =>
        (character >= 0x41 && character <= 0x5A) ||
        (character >= 0x61 && character <= 0x7A);

    void skipWhitespaces() {
      while (index < length && isWhitespace(comment.codeUnitAt(index))) {
        index++;
      }
    }

    // Count the number of `/` characters at the beginning.
    while (index < length && comment.codeUnitAt(index) == 0x2F) {
      index++;
    }
    int slashCount = index;

    skipWhitespaces();
    if (index == length) {
      // This is not an attempted language version override comment.
      return false;
    }

    bool atSignPresent = comment.codeUnitAt(index) == 0x40;
    if (atSignPresent) {
      index++;
    }
    if (length - index < 4) {
      // This is not an attempted language version override comment.
      return false;
    }

    String possibleDart = comment.substring(index, index + 4);
    if (possibleDart.toLowerCase() != 'dart') {
      // This is not an attempted language version override comment.
      return false;
    }

    index += 4;
    skipWhitespaces();
    if (index == length) {
      // This is not an attempted language version override comment.
      return false;
    }

    // The separator between "@dart" and the version number.
    int dartVersionSeparatorStartIndex = index;
    // Move through any other consecutive punctuation, whitespace,
    while (index < length) {
      int possibleSeparatorCharacter = comment.codeUnitAt(index);
      if (isNumeric(possibleSeparatorCharacter) ||
          isAlphabetical(possibleSeparatorCharacter) ||
          isWhitespace(possibleSeparatorCharacter)) {
        break;
      }
      index++;
    }
    if (index == length) {
      // This is not an attempted language version override comment.
      return false;
    }

    int dartVersionSeparatorLength = index - dartVersionSeparatorStartIndex;
    skipWhitespaces();
    if (index == length) {
      // This is not an attempted language version override comment.
      return false;
    }

    bool containsInvalidVersionNumberPrefix = false;
    if (isAlphabetical(comment.codeUnitAt(index))) {
      containsInvalidVersionNumberPrefix = true;
      index++;
      if (index == length) {
        // This is not an attempted language version override comment.
        return false;
      }
    }

    if (!isNumeric(comment.codeUnitAt(index))) {
      // This is not an attempted language version override comment.
      return false;
    }

    if (index + 1 < length && isAlphabetical(comment.codeUnitAt(index + 1))) {
      // This is not an attempted language version override comment.
      return false;
    }

    if (!atSignPresent && dartVersionSeparatorLength == 0) {
      // The comment is too different from a valid language version override
      // comment, like "/// dart2 is great".
      return false;
    }

    // At this point, the comment is considered an "attempted" language version
    // override comment. Check for all issues which would make it an invalid
    // language version override comment.

    if (slashCount > 2) {
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES,
          offset,
          length);
      return false;
    }

    if (!atSignPresent) {
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN, offset, length);
      return false;
    }

    if (possibleDart != 'dart') {
      // The 4 characters after `@` are "dart", but in the wrong case.
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE,
          offset,
          length);
      return false;
    }

    if (dartVersionSeparatorLength != 1 ||
        comment.codeUnitAt(dartVersionSeparatorStartIndex) != 0x3D) {
      // The separator between "@dart" and the version number is either not
      // present, or is not a single "=" character.
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS, offset, length);
      return false;
    }

    if (containsInvalidVersionNumberPrefix) {
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX, offset, length);
      return false;
    }

    void reportInvalidNumber() {
      _errorReporter.reportErrorForOffset(
          HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER, offset, length);
    }

    // Nothing preceding the version number makes this comment invalid. Check
    // the format of the version number, and trailing characters.

    // Skip major version.
    while (index < length && isNumeric(comment.codeUnitAt(index))) {
      index++;
    }

    // Skip '.' separator.
    if (index == length || comment.codeUnitAt(index) != 0x2E) {
      reportInvalidNumber();
      return false;
    }
    index++;

    // Skip minor version.
    while (index < length && isNumeric(comment.codeUnitAt(index))) {
      index++;
    }

    skipWhitespaces();

    // OK, no trailing characters.
    if (index == length) {
      return true;
    }

    // This comment is a valid language version override, except for trailing
    // characters.
    _errorReporter.reportErrorForOffset(
        HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS,
        offset,
        length);
    return false;
  }

  /// Verify that all language version overrides are before declarations.
  void _verifyMisplaced(CompilationUnit unit) {
    Token firstMeaningfulToken;
    if (unit.directives.isNotEmpty) {
      firstMeaningfulToken = unit.directives.first.beginToken;
    } else if (unit.declarations.isNotEmpty) {
      firstMeaningfulToken = unit.declarations.first.beginToken;
    } else {
      return;
    }

    var token = firstMeaningfulToken.next;
    while (token != null) {
      if (token.offset > firstMeaningfulToken.offset) {
        var commentToken = token.precedingComments;
        for (; commentToken != null; commentToken = commentToken.next) {
          var lexeme = commentToken.lexeme;

          var match = _overrideCommentLine.firstMatch(lexeme);
          if (match != null) {
            var atDartStart = lexeme.indexOf('@dart');
            _errorReporter.reportErrorForOffset(
              HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION,
              commentToken.offset + atDartStart,
              match.end - atDartStart,
            );
          }
        }
      }

      if (token.next == token) {
        break;
      } else {
        token = token.next;
      }
    }
  }
}
