// 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 'package:analysis_server/src/services/correction/fix/data_driven/accessor.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/variable_scope.dart';
import 'package:analyzer/error/listener.dart';

/// A parser for the textual representation of a code fragment.
class CodeFragmentParser {
  /// The error reporter to which diagnostics will be reported.
  final ErrorReporter errorReporter;

  /// The scope in which variables can be looked up.
  VariableScope variableScope;

  /// The amount to be added to translate from offsets within the content to
  /// offsets within the file.
  int delta;

  /// The tokens being parsed.
  /* late */ List<_Token> tokens;

  /// The index in the [tokens] of the next token to be consumed.
  int currentIndex = 0;

  /// Initialize a newly created parser to report errors to the [errorReporter].
  CodeFragmentParser(this.errorReporter, {VariableScope scope})
      : variableScope = scope ?? VariableScope(null, {});

  /// Return the current token, or `null` if the end of the tokens has been
  /// reached.
  _Token get currentToken =>
      currentIndex < tokens.length ? tokens[currentIndex] : null;

  /// Advance to the next token.
  void advance() {
    if (currentIndex < tokens.length) {
      currentIndex++;
    }
  }

  /// Parse the [content] into a list of accessors. Add the [delta] to translate
  /// from offsets within the content to offsets within the file.
  ///
  /// <content> ::=
  ///   <accessor> ('.' <accessor>)*
  List<Accessor> parseAccessors(String content, int delta) {
    this.delta = delta;
    tokens = _CodeFragmentScanner(content, delta, errorReporter).scan();
    if (tokens == null) {
      // The error has already been reported.
      return null;
    }
    currentIndex = 0;
    var accessors = <Accessor>[];
    var accessor = _parseAccessor();
    if (accessor == null) {
      return accessors;
    }
    accessors.add(accessor);
    while (currentIndex < tokens.length) {
      var token = currentToken;
      if (token.kind == _TokenKind.period) {
        advance();
        accessor = _parseAccessor();
        if (accessor == null) {
          return accessors;
        }
        accessors.add(accessor);
      } else {
        errorReporter.reportErrorForOffset(TransformSetErrorCode.wrongToken,
            token.offset + delta, token.length, ['.', token.kind.displayName]);
        return null;
      }
    }
    return accessors;
  }

  /// Parse the [content] into a condition. Add the [delta] to translate
  /// from offsets within the content to offsets within the file.
  ///
  /// <content> ::=
  ///   <logicalExpression>
  Expression parseCondition(String content, int delta) {
    this.delta = delta;
    tokens = _CodeFragmentScanner(content, delta, errorReporter).scan();
    if (tokens == null) {
      // The error has already been reported.
      return null;
    }
    currentIndex = 0;
    var expression = _parseLogicalAndExpression();
    if (currentIndex < tokens.length) {
      var token = tokens[currentIndex];
      errorReporter.reportErrorForOffset(TransformSetErrorCode.unexpectedToken,
          token.offset + delta, token.length, [token.kind.displayName]);
      return null;
    }
    return expression;
  }

  /// Return the current token if it exists and has one of the [validKinds].
  /// Report an error and return `null` if those conditions aren't met.
  _Token _expect(List<_TokenKind> validKinds) {
    String validKindsDisplayString() {
      var buffer = StringBuffer();
      for (var i = 0; i < validKinds.length; i++) {
        if (i > 0) {
          if (i == validKinds.length - 1) {
            buffer.write(' or ');
          } else {
            buffer.write(', ');
          }
        }
        buffer.write(validKinds[i].displayName);
      }
      return buffer.toString();
    }

    var token = currentToken;
    if (token == null) {
      var offset = 0;
      var length = 0;
      if (tokens.isNotEmpty) {
        var last = tokens.last;
        offset = last.offset;
        length = last.length;
      }
      errorReporter.reportErrorForOffset(TransformSetErrorCode.missingToken,
          offset + delta, length, [validKindsDisplayString()]);
      return null;
    }
    if (!validKinds.contains(token.kind)) {
      errorReporter.reportErrorForOffset(
          TransformSetErrorCode.wrongToken,
          token.offset + delta,
          token.length,
          [validKindsDisplayString(), token.kind.displayName]);
      return null;
    }
    return token;
  }

  /// Parse an accessor.
  ///
  /// <accessor> ::=
  ///   <identifier> '[' (<integer> | <identifier>) ']'
  Accessor _parseAccessor() {
    var token = _expect(const [_TokenKind.identifier]);
    if (token == null) {
      // The error has already been reported.
      return null;
    }
    var identifier = token.lexeme;
    if (identifier == 'arguments') {
      advance();
      token = _expect(const [_TokenKind.openSquareBracket]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      advance();
      token = _expect(const [_TokenKind.identifier, _TokenKind.integer]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      ParameterReference reference;
      if (token.kind == _TokenKind.identifier) {
        reference = NamedParameterReference(token.lexeme);
      } else {
        var argumentIndex = int.parse(token.lexeme);
        reference = PositionalParameterReference(argumentIndex);
      }
      advance();
      token = _expect(const [_TokenKind.closeSquareBracket]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      advance();
      return ArgumentAccessor(reference);
    } else if (identifier == 'typeArguments') {
      advance();
      token = _expect(const [_TokenKind.openSquareBracket]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      advance();
      token = _expect(const [_TokenKind.integer]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      advance();
      var argumentIndex = int.parse(token.lexeme);
      token = _expect(const [_TokenKind.closeSquareBracket]);
      if (token == null) {
        // The error has already been reported.
        return null;
      }
      advance();
      return TypeArgumentAccessor(argumentIndex);
    } else {
      errorReporter.reportErrorForOffset(TransformSetErrorCode.unknownAccessor,
          token.offset + delta, token.length, [identifier]);
      return null;
    }
  }

  /// Parse a logical expression.
  ///
  /// <equalityExpression> ::=
  ///   <primaryExpression> (<comparisonOperator> <primaryExpression>)?
  /// <comparisonOperator> ::=
  ///   '==' | '!='
  Expression _parseEqualityExpression() {
    var expression = _parsePrimaryExpression();
    if (expression == null) {
      return null;
    }
    if (currentIndex >= tokens.length) {
      return expression;
    }
    var kind = currentToken.kind;
    if (kind == _TokenKind.equal || kind == _TokenKind.notEqual) {
      advance();
      var operator =
          kind == _TokenKind.equal ? Operator.equal : Operator.notEqual;
      var rightOperand = _parsePrimaryExpression();
      if (rightOperand == null) {
        return null;
      }
      expression = BinaryExpression(expression, operator, rightOperand);
    }
    return expression;
  }

  /// Parse a logical expression.
  ///
  /// <logicalExpression> ::=
  ///   <equalityExpression> ('&&' <equalityExpression>)*
  Expression _parseLogicalAndExpression() {
    var expression = _parseEqualityExpression();
    if (expression == null) {
      return null;
    }
    if (currentIndex >= tokens.length) {
      return expression;
    }
    var kind = currentToken.kind;
    while (kind == _TokenKind.and) {
      advance();
      var rightOperand = _parseEqualityExpression();
      if (rightOperand == null) {
        return null;
      }
      expression = BinaryExpression(expression, Operator.and, rightOperand);
      if (currentIndex >= tokens.length) {
        return expression;
      }
      kind = currentToken.kind;
    }
    return expression;
  }

  /// Parse a logical expression.
  ///
  /// <primaryExpression> ::=
  ///   <identifier> | <string>
  Expression _parsePrimaryExpression() {
    var token = currentToken;
    var kind = token?.kind;
    if (kind == _TokenKind.identifier) {
      advance();
      var variableName = token.lexeme;
      var generator = variableScope.lookup(variableName);
      if (generator == null) {
        errorReporter.reportErrorForOffset(
            TransformSetErrorCode.undefinedVariable,
            token.offset + delta,
            token.length,
            [variableName]);
        return null;
      }
      return VariableReference(generator);
    } else if (kind == _TokenKind.string) {
      advance();
      var lexeme = token.lexeme;
      var value = lexeme.substring(1, lexeme.length - 1);
      return LiteralString(value);
    }
    int offset;
    int length;
    if (token == null) {
      if (tokens.isNotEmpty) {
        token = tokens[tokens.length - 1];
        offset = token.offset + delta;
        length = token.length;
      } else {
        offset = delta;
        length = 0;
      }
    } else {
      offset = token.offset + delta;
      length = token.length;
    }
    errorReporter.reportErrorForOffset(
        TransformSetErrorCode.expectedPrimary, offset, length);
    return null;
  }
}

/// A scanner for the textual representation of a code fragment.
class _CodeFragmentScanner {
  static final int $0 = '0'.codeUnitAt(0);
  static final int $9 = '9'.codeUnitAt(0);
  static final int $a = 'a'.codeUnitAt(0);
  static final int $z = 'z'.codeUnitAt(0);
  static final int $A = 'A'.codeUnitAt(0);
  static final int $Z = 'Z'.codeUnitAt(0);

  static final int ampersand = '&'.codeUnitAt(0);
  static final int bang = '!'.codeUnitAt(0);
  static final int closeSquareBracket = ']'.codeUnitAt(0);
  static final int carriageReturn = '\r'.codeUnitAt(0);
  static final int equal = '='.codeUnitAt(0);
  static final int newline = '\n'.codeUnitAt(0);
  static final int openSquareBracket = '['.codeUnitAt(0);
  static final int period = '.'.codeUnitAt(0);
  static final int singleQuote = "'".codeUnitAt(0);
  static final int space = ' '.codeUnitAt(0);

  /// The string being scanned.
  final String content;

  /// The length of the string being scanned.
  final int length;

  /// The offset in the file of the first character in the string being scanned.
  final int delta;

  /// The error reporter to which diagnostics will be reported.
  final ErrorReporter errorReporter;

  /// Initialize a newly created scanner to scan the given [content].
  _CodeFragmentScanner(this.content, this.delta, this.errorReporter)
      : length = content.length;

  /// Return the tokens in the content, or `null` if there is an error in the
  /// content that prevents it from being scanned.
  List<_Token> scan() {
    var length = content.length;

    int peekAt(int offset) {
      if (offset > length) {
        return -1;
      }
      return content.codeUnitAt(offset);
    }

    var offset = _skipWhitespace(0);
    var tokens = <_Token>[];
    while (offset < length) {
      var char = content.codeUnitAt(offset);
      if (char == closeSquareBracket) {
        tokens.add(_Token(offset, _TokenKind.closeSquareBracket, ']'));
        offset++;
      } else if (char == openSquareBracket) {
        tokens.add(_Token(offset, _TokenKind.openSquareBracket, '['));
        offset++;
      } else if (char == period) {
        tokens.add(_Token(offset, _TokenKind.period, '.'));
        offset++;
      } else if (char == ampersand) {
        if (peekAt(offset + 1) != ampersand) {
          return _reportInvalidCharacter(offset);
        }
        tokens.add(_Token(offset, _TokenKind.and, '&&'));
        offset += 2;
      } else if (char == bang) {
        if (peekAt(offset + 1) != equal) {
          return _reportInvalidCharacter(offset);
        }
        tokens.add(_Token(offset, _TokenKind.notEqual, '!='));
        offset += 2;
      } else if (char == equal) {
        if (peekAt(offset + 1) != equal) {
          return _reportInvalidCharacter(offset);
        }
        tokens.add(_Token(offset, _TokenKind.equal, '=='));
        offset += 2;
      } else if (char == singleQuote) {
        var start = offset;
        offset++;
        while (offset < length && content.codeUnitAt(offset) != singleQuote) {
          offset++;
        }
        offset++;
        tokens.add(
            _Token(start, _TokenKind.string, content.substring(start, offset)));
      } else if (_isLetter(char)) {
        var start = offset;
        offset++;
        while (offset < length && _isLetter(content.codeUnitAt(offset))) {
          offset++;
        }
        tokens.add(_Token(
            start, _TokenKind.identifier, content.substring(start, offset)));
      } else if (_isDigit(char)) {
        var start = offset;
        offset++;
        while (offset < length && _isDigit(content.codeUnitAt(offset))) {
          offset++;
        }
        tokens.add(_Token(
            start, _TokenKind.integer, content.substring(start, offset)));
      } else {
        return _reportInvalidCharacter(offset);
      }
      offset = _skipWhitespace(offset);
    }
    return tokens;
  }

  /// Return `true` if the [char] is a digit.
  bool _isDigit(int char) => char >= $0 && char <= $9;

  /// Return `true` if the [char] is a letter.
  bool _isLetter(int char) =>
      (char >= $a && char <= $z) || (char >= $A && char <= $Z);

  /// Return `true` if the [char] is a whitespace character.
  bool _isWhitespace(int char) =>
      char == space || char == newline || char == carriageReturn;

  /// Report the presence of an invalid character at the given [offset].
  Null _reportInvalidCharacter(int offset) {
    errorReporter.reportErrorForOffset(TransformSetErrorCode.invalidCharacter,
        offset + delta, 1, [content.substring(offset, offset + 1)]);
    return null;
  }

  /// Return the index of the first character at or after the given [offset]
  /// that isn't a whitespace character.
  int _skipWhitespace(int offset) {
    while (offset < length) {
      var char = content.codeUnitAt(offset);
      if (!_isWhitespace(char)) {
        return offset;
      }
      offset++;
    }
    return offset;
  }
}

/// A token in a code fragment's string representation.
class _Token {
  /// The offset of the token.
  final int offset;

  /// The kind of the token.
  final _TokenKind kind;

  /// The lexeme of the token.
  final String lexeme;

  /// Initialize a newly created token.
  _Token(this.offset, this.kind, this.lexeme);

  /// Return the length of this token.
  int get length => lexeme.length;
}

/// An indication of the kind of a token.
enum _TokenKind {
  and,
  closeSquareBracket,
  equal,
  identifier,
  integer,
  notEqual,
  openSquareBracket,
  period,
  string,
}

extension on _TokenKind {
  String get displayName {
    switch (this) {
      case _TokenKind.and:
        return "'&&'";
      case _TokenKind.closeSquareBracket:
        return "']'";
      case _TokenKind.equal:
        return "'=='";
      case _TokenKind.identifier:
        return 'an identifier';
      case _TokenKind.integer:
        return 'an integer';
      case _TokenKind.notEqual:
        return "'!='";
      case _TokenKind.openSquareBracket:
        return "'['";
      case _TokenKind.period:
        return "'.'";
      case _TokenKind.string:
        return 'a string';
    }
    return '';
  }
}
