#ifndef EXPERIMENTAL_LAVM_LEXER_H_
#define EXPERIMENTAL_LAVM_LEXER_H_

#include <iostream>

#include "llvm/ADT/StringRef.h"

namespace mlir {
namespace lavm {

using Token = llvm::StringRef;

class Lexer {
 public:
  static bool is_newline(char c) { return c == '\n'; }

  static bool is_whitespace(char c) {
    return is_newline(c) || c == ' ' || c == '\t';
  }

  static bool is_list_separator(char c) { return c == ','; }

  static bool is_open_paren(char c) { return c == '('; }

  static bool is_close_paren(char c) { return c == ')'; }

  static bool is_open_angle(char c) {
    return false;  // c == '<';
  }

  static bool is_close_angle(char c) {
    return false;  // c == '>'; conflicts with "->"
  }

  static bool is_separator(char c) {
    return is_list_separator(c) || is_open_paren(c) || is_close_paren(c) ||
           is_open_angle(c) || is_close_angle(c) || c == ':';
  }

  static bool is_terminator(char c) { return c == ';'; }

  static bool is_name_marker(char c) { return c == '%'; }

  static bool is_cache_marker(char c) { return c == '$'; }

  static bool is_comment(char c) { return c == '#'; }

  static bool is_end(char c) { return c == '\0'; }

  static bool is_end(Token token) { return token.empty(); }

  static bool is_separator(Token token) {
    return token.size() == 1 && is_separator(token.front());
  }

  static bool is_terminator(Token token) {
    return token.size() == 1 && is_terminator(token.front());
  }

  static bool is_arrow(Token token) {
    return token.size() == 2 && token.front() == '-' && token.back() == '>';
  }

  static std::string TokenToString(Token token) {
    return is_end(token) ? "END-OF-FILE" : token.str();
  }

  static Token FindToken(const char* start_at,
                         bool skip_terminators_and_separators = true) {
    const char* first = start_at;
    if (is_end(*first)) {
      return "";
    }
    while (is_whitespace(*first) ||
           (skip_terminators_and_separators &&
            (is_terminator(*first) || is_separator(*first)))) {
      first++;
    }
    if (is_separator(*first) || is_terminator(*first)) {
      assert(!skip_terminators_and_separators);
      return Token(first, 1);
    }
    if (is_comment(*first)) {
      // Skip the rest of the line
      while (!is_end(*first) && !is_newline(*first)) {
        first++;
      }
      // Pass either 'end' or 'newline' in.
      return FindToken(first, skip_terminators_and_separators);
    }
    const char* last = first;
    while (!is_end(*last) && !is_whitespace(*last) && !is_separator(*last) &&
           !is_terminator(*last))
      last++;
    return Token(first, last - first);
  }

  static Token NextToken(Token token,
                         bool skip_terminators_and_separators = true) {
    const char* start_at = token.data() + token.size();
    Token next = FindToken(start_at, skip_terminators_and_separators);
    return next;
  }

  static bool Eat(const std::string& food, Token* token,
                  bool skip_terminators_and_separators = true) {
    if (food == token->str()) {
      *token = NextToken(*token, skip_terminators_and_separators);
      return true;
    }
    return false;
  }

  static bool EatOrError(const std::string& food, Token* token,
                         bool skip_terminators_and_separators = true) {
    return Eat(food, token, skip_terminators_and_separators) ||
           ParseErrorExpected(food, *token);
  }

  static bool ParseError(const std::string& message) {
    std::cerr << "ERROR: " << message << std::endl;
    return false;
  }

  static bool ParseErrorExpected(const std::string& expected, Token token) {
    ParseError("Expect to see '" + expected + "', instead '" +
               TokenToString(token) + "' found");
    return false;
  }

  static bool ParseWarning(const std::string& message) {
    // FIXME? suppress warnings if any error messages had been emitted.
    std::cerr << "WARNING: " << message << std::endl;
    return false;
  }

  // static Type ParseType(Token token, MLIRContext* context) {
  //   // suppress "unexpected character" error message after the type token
  //   std::string t(token.begin(), token.end());
  //   return mlir::parseType(t, context);
  // }
};

}  // namespace lavm
}  // namespace mlir

#endif  // EXPERIMENTAL_LAVM_LEXER_H_
