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

#ifndef SRC_DEVELOPER_SHELL_PARSER_AST_H_
#define SRC_DEVELOPER_SHELL_PARSER_AST_H_

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

namespace shell::parser::ast {

class Node;
class Terminal;
class Nonterminal;
class Error;
class Program;
class VariableDecl;
class Identifier;
class Integer;
class Expression;
class DecimalGroup;
class HexGroup;
class UnescapedIdentifier;
class StringEntity;
class EscapeSequence;
class PathElement;
class PathEscape;
class PathSeparator;
class Operator;
class String;
class Object;
class Field;
class Path;
class AddSub;

class NodeVisitor;

// A node in our AST.
class Node {
  friend class NodeVisitor;

 public:
  explicit Node(size_t start) : start_(start) {}
  virtual ~Node() = default;

  size_t start() const { return start_; }

  // Child nodes of this node. Always empty for terminals, may be empty for non-terminals.
  virtual const std::vector<std::shared_ptr<Node>>& Children() const = 0;

  // Create an s-expression-like string representation of this node. We don't store the parsed text
  // in the node itself so we must be passed the original parsed string.
  virtual std::string ToString(std::string_view unit) const = 0;

  // Number of characters this node corresponds to in the original text.
  virtual size_t Size() const = 0;

  // Whether this node marks a parse error.
  virtual bool IsError() const { return false; }

  // Whether this node is a whitespace node.
  virtual bool IsWhitespace() const { return false; }

  // Whether this node or any of its children contains parse errors.
  virtual bool HasErrors() const { return IsError(); }

  // Visit this node with a visitor.
  virtual void Visit(NodeVisitor* visitor) const = 0;

  // Downcasting methods
  virtual Error* AsError() { return nullptr; }
  const Error* AsError() const { return const_cast<Node*>(this)->AsError(); }
  virtual Program* AsProgram() { return nullptr; }
  const Program* AsProgram() const { return const_cast<Node*>(this)->AsProgram(); }
  virtual VariableDecl* AsVariableDecl() { return nullptr; }
  const VariableDecl* AsVariableDecl() const { return const_cast<Node*>(this)->AsVariableDecl(); }
  virtual Identifier* AsIdentifier() { return nullptr; }
  const Identifier* AsIdentifier() const { return const_cast<Node*>(this)->AsIdentifier(); }
  virtual Integer* AsInteger() { return nullptr; }
  const Integer* AsInteger() const { return const_cast<Node*>(this)->AsInteger(); }
  virtual Expression* AsExpression() { return nullptr; }
  const Expression* AsExpression() const { return const_cast<Node*>(this)->AsExpression(); }
  virtual DecimalGroup* AsDecimalGroup() { return nullptr; }
  const DecimalGroup* AsDecimalGroup() const { return const_cast<Node*>(this)->AsDecimalGroup(); }
  virtual HexGroup* AsHexGroup() { return nullptr; }
  const HexGroup* AsHexGroup() const { return const_cast<Node*>(this)->AsHexGroup(); }
  virtual UnescapedIdentifier* AsUnescapedIdentifier() { return nullptr; }
  const UnescapedIdentifier* AsUnescapedIdentifier() const {
    return const_cast<Node*>(this)->AsUnescapedIdentifier();
  }
  virtual StringEntity* AsStringEntity() { return nullptr; }
  const StringEntity* AsStringEntity() const { return const_cast<Node*>(this)->AsStringEntity(); }
  virtual EscapeSequence* AsEscapeSequence() { return nullptr; }
  const EscapeSequence* AsEscapeSequence() const {
    return const_cast<Node*>(this)->AsEscapeSequence();
  }
  virtual PathElement* AsPathElement() { return nullptr; }
  const PathElement* AsPathElement() const { return const_cast<Node*>(this)->AsPathElement(); }
  virtual PathEscape* AsPathEscape() { return nullptr; }
  const PathEscape* AsPathEscape() const { return const_cast<Node*>(this)->AsPathEscape(); }
  virtual Operator* AsOperator() { return nullptr; }
  const Operator* AsOperator() const { return const_cast<Node*>(this)->AsOperator(); }
  virtual String* AsString() { return nullptr; }
  const String* AsString() const { return const_cast<Node*>(this)->AsString(); }
  virtual Object* AsObject() { return nullptr; }
  const Object* AsObject() const { return const_cast<Node*>(this)->AsObject(); }
  virtual Field* AsField() { return nullptr; }
  const Field* AsField() const { return const_cast<Node*>(this)->AsField(); }
  virtual Path* AsPath() { return nullptr; }
  const Path* AsPath() const { return const_cast<Node*>(this)->AsPath(); }
  virtual AddSub* AsAddSub() { return nullptr; }
  const AddSub* AsAddSub() const { return const_cast<Node*>(this)->AsAddSub(); }

  // ID methods for keywords
  virtual bool IsConst() const { return false; }
  virtual bool IsVar() const { return false; }
  virtual bool IsFieldSeparator() const { return false; }
  virtual bool IsPathSeparator() const { return false; }

 private:
  // Offset into the original text where the text this node corresponds to starts.
  const size_t start_;
};

// Superclass of all terminal nodes in our AST.
class Terminal : public Node {
 public:
  Terminal(size_t start, size_t size, std::string_view /*content*/) : Node(start), size_(size) {}

  const std::vector<std::shared_ptr<Node>>& Children() const override { return kEmptyChildren; }
  size_t Size() const override { return size_; }

  std::string ToString(std::string_view unit) const override;
  void Visit(NodeVisitor* visitor) const override;

 private:
  static const std::vector<std::shared_ptr<Node>> kEmptyChildren;

  const size_t size_;
};

class Error : public Terminal {
 public:
  Error(size_t start, size_t size, const std::string& message)
      : Terminal(start, size, ""), message_(message) {}

  const std::string& message() const { return message_; }

  bool IsError() const override { return true; }

  std::string ToString(std::string_view unit) const override;
  Error* AsError() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  const std::string message_;
};

// Terminal representing a ":".
class FieldSeparator : public Terminal {
 public:
  FieldSeparator(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content) {}

  bool IsFieldSeparator() const override { return true; }
  void Visit(NodeVisitor* visitor) const override;
};

// Terminal representing the "const" keyword.
class Const : public Terminal {
 public:
  Const(size_t start, size_t size, std::string_view content) : Terminal(start, size, content) {}

  bool IsConst() const override { return true; }
  void Visit(NodeVisitor* visitor) const override;
};

// Terminal representing the "var" keyword.
class Var : public Terminal {
 public:
  Var(size_t start, size_t size, std::string_view content) : Terminal(start, size, content) {}

  bool IsVar() const override { return true; }
  void Visit(NodeVisitor* visitor) const override;
};

// Terminal representing a sequence of decimal digits.
class DecimalGroup : public Terminal {
 public:
  DecimalGroup(size_t start, size_t size, std::string_view content);

  size_t digits() const { return digits_; }
  uint64_t value() const { return value_; }

  DecimalGroup* AsDecimalGroup() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  size_t digits_;
  uint64_t value_ = 0;
};

// Terminal representing a sequence of hex digits.
class HexGroup : public Terminal {
 public:
  HexGroup(size_t start, size_t size, std::string_view content);

  size_t digits() const { return digits_; }
  uint64_t value() const { return value_; }

  HexGroup* AsHexGroup() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  size_t digits_;
  uint64_t value_ = 0;
};

// Terminal representing an unescaped identifier
class UnescapedIdentifier : public Terminal {
 public:
  UnescapedIdentifier(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content), identifier_(content) {}

  const std::string& identifier() const { return identifier_; }

  UnescapedIdentifier* AsUnescapedIdentifier() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string identifier_ = "";
};

// Terminal representing a piece of a string literal.
class StringEntity : public Terminal {
 public:
  StringEntity(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content), content_(content) {}

  const std::string& content() const { return content_; }

  StringEntity* AsStringEntity() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string content_ = "";
};

// Terminal representing a piece of an escape sequence in a string literal.
class EscapeSequence : public StringEntity {
 public:
  EscapeSequence(size_t start, size_t size, std::string_view content)
      : StringEntity(start, size, Decode(content)) {}

  EscapeSequence* AsEscapeSequence() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  static std::string Decode(std::string_view sequence);
};

// Terminal representing a continuous piece of a path.
class PathElement : public Terminal {
 public:
  PathElement(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content), content_(content) {}

  const std::string& content() const { return content_; }

  PathElement* AsPathElement() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string content_ = "";
};

// Terminal representing a piece of an escape sequence in a path.
class PathEscape : public PathElement {
 public:
  PathEscape(size_t start, size_t size, std::string_view content)
      : PathElement(start, size, content.substr(1)) {}

  PathEscape* AsPathEscape() override { return this; }
  void Visit(NodeVisitor* visitor) const override;
};

// Terminal representing a path separator.
class PathSeparator : public Terminal {
 public:
  PathSeparator(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content) {}

  bool IsPathSeparator() const override { return true; }
  void Visit(NodeVisitor* visitor) const override;
};

// Terminal representing an operator.
class Operator : public Terminal {
 public:
  Operator(size_t start, size_t size, std::string_view content)
      : Terminal(start, size, content), operator_(content) {}

  const std::string& op() const { return operator_; }

  Operator* AsOperator() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string operator_ = "";
};

// Superclass of all non-terminal nodes in our AST.
class Nonterminal : public Node {
 public:
  Nonterminal(size_t start, std::vector<std::shared_ptr<Node>> children)
      : Node(start), children_(std::move(children)) {
    for (const auto& child : children_) {
      if (child->HasErrors()) {
        has_errors_ = true;
        break;
      }
    }
  }

  // Name of this node as a string.
  virtual std::string_view Name() const = 0;

  const std::vector<std::shared_ptr<Node>>& Children() const override { return children_; }
  size_t Size() const override {
    if (children_.empty()) {
      return 0;
    } else {
      return children_.back()->start() - start() + children_.back()->Size();
    }
  }

  std::string ToString(std::string_view unit) const override;

  bool HasErrors() const override { return has_errors_; }

  void Visit(NodeVisitor* visitor) const override;

 private:
  bool has_errors_ = false;
  std::vector<std::shared_ptr<Node>> children_;
};

// Result of an attempt to parse a single token. Usually that will result in a terminal, but if
// there are errors, we may get one of these instead. Its children will be error nodes and the
// fragments of the token that parsed correctly.
class TokenResult : public Nonterminal {
 public:
  TokenResult(size_t start, std::vector<std::shared_ptr<Node>> children)
      : Nonterminal(start, std::move(children)) {}

  std::string_view Name() const override { return ""; }

  // If one of these ends up in output outside of the Token() combinator, then it's definitely an
  // error.
  bool IsError() const override { return true; }
};

class Whitespace : public Nonterminal {
 public:
  Whitespace(size_t start, std::vector<std::shared_ptr<Node>> children)
      : Nonterminal(start, std::move(children)) {}

  std::string_view Name() const override { return "Whitespace"; }
  bool IsWhitespace() const override { return true; }
};

class Program : public Nonterminal {
 public:
  Program(size_t start, std::vector<std::shared_ptr<Node>> children)
      : Nonterminal(start, std::move(children)) {}

  std::string_view Name() const override { return "Program"; }
  Program* AsProgram() override { return this; }
  void Visit(NodeVisitor* visitor) const override;
};

class VariableDecl : public Nonterminal {
 public:
  VariableDecl(size_t start, std::vector<std::shared_ptr<Node>> children);

  const std::string& identifier() const { return identifier_; }
  Expression* expression() const { return expression_; }
  bool is_const() const { return is_const_; }

  std::string_view Name() const override { return "VariableDecl"; }
  VariableDecl* AsVariableDecl() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  Expression* expression_ = nullptr;
  bool is_const_ = false;
  std::string identifier_ = "";
};

class Integer : public Nonterminal {
 public:
  Integer(size_t start, std::vector<std::shared_ptr<Node>> children);

  uint64_t value() const { return value_; }

  std::string_view Name() const override { return "Integer"; }

  Integer* AsInteger() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 public:
  uint64_t value_ = 0;
};

class String : public Nonterminal {
 public:
  String(size_t start, std::vector<std::shared_ptr<Node>> children);

  const std::string& value() const { return value_; }

  std::string_view Name() const override { return "String"; }

  String* AsString() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 public:
  std::string value_;
};

class Identifier : public Nonterminal {
 public:
  Identifier(size_t start, std::vector<std::shared_ptr<Node>> children);

  const std::string& identifier() const { return identifier_; }

  std::string_view Name() const override { return "Identifier"; }

  Identifier* AsIdentifier() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string identifier_;
};

class Object : public Nonterminal {
 public:
  Object(size_t start, std::vector<std::shared_ptr<Node>> children);

  const std::vector<Field*> fields() const { return fields_; }

  std::string_view Name() const override { return "Object"; }

  Object* AsObject() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::vector<Field*> fields_;
};

class Field : public Nonterminal {
 public:
  Field(size_t start, std::vector<std::shared_ptr<Node>> children);

  const std::string& name() const { return name_; }
  Node* value() const { return value_; }

  std::string_view Name() const override { return "Field"; }

  Field* AsField() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  std::string name_;
  Node* value_ = nullptr;
};

class Path : public Nonterminal {
 public:
  Path(size_t start, std::vector<std::shared_ptr<Node>> children);

  bool is_local() const { return is_local_; }
  const std::vector<std::string>& elements() const { return elements_; }

  std::string_view Name() const override { return "Path"; }

  Path* AsPath() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  bool is_local_;
  std::vector<std::string> elements_;
};

class AddSub : public Nonterminal {
 public:
  enum Type {
    kAdd,
    kSubtract,
  };

  AddSub(size_t start, std::vector<std::shared_ptr<Node>> children);

  Type type() const { return type_; }
  Node* a() const { return a_; }
  Node* b() const { return b_; }

  std::string_view Name() const override { return "AddSub"; }

  AddSub* AsAddSub() override { return this; }
  void Visit(NodeVisitor* visitor) const override;

 private:
  Type type_ = kAdd;
  Node* a_ = nullptr;
  Node* b_ = nullptr;
};

class Expression : public Nonterminal {
 public:
  Expression(size_t start, std::vector<std::shared_ptr<Node>> children)
      : Nonterminal(start, std::move(children)) {}

  std::string_view Name() const override { return "Expression"; }
  Expression* AsExpression() override { return this; }
  void Visit(NodeVisitor* visitor) const override;
};

// Visitor for AST nodes.
class NodeVisitor {
  friend class Node;
  friend class Terminal;
  friend class Nonterminal;
  friend class Error;
  friend class Var;
  friend class Const;
  friend class FieldSeparator;
  friend class Program;
  friend class VariableDecl;
  friend class Identifier;
  friend class Integer;
  friend class Expression;
  friend class DecimalGroup;
  friend class HexGroup;
  friend class UnescapedIdentifier;
  friend class StringEntity;
  friend class EscapeSequence;
  friend class PathElement;
  friend class PathEscape;
  friend class PathSeparator;
  friend class Operator;
  friend class String;
  friend class Object;
  friend class Field;
  friend class Path;
  friend class AddSub;

 protected:
  virtual void VisitNode(const Node& node){};
  virtual void VisitTerminal(const Terminal& node) { VisitNode(node); };
  virtual void VisitNonterminal(const Nonterminal& node) { VisitNode(node); };
  virtual void VisitError(const Error& node) { VisitTerminal(node); };
  virtual void VisitConst(const Const& node) { VisitTerminal(node); };
  virtual void VisitVar(const Var& node) { VisitTerminal(node); };
  virtual void VisitFieldSeparator(const FieldSeparator& node) { VisitTerminal(node); };
  virtual void VisitProgram(const Program& node) { VisitNonterminal(node); };
  virtual void VisitVariableDecl(const VariableDecl& node) { VisitNonterminal(node); };
  virtual void VisitIdentifier(const Identifier& node) { VisitNonterminal(node); };
  virtual void VisitInteger(const Integer& node) { VisitNonterminal(node); };
  virtual void VisitExpression(const Expression& node) { VisitNonterminal(node); };
  virtual void VisitDecimalGroup(const DecimalGroup& node) { VisitTerminal(node); };
  virtual void VisitHexGroup(const HexGroup& node) { VisitTerminal(node); };
  virtual void VisitUnescapedIdentifier(const UnescapedIdentifier& node) { VisitTerminal(node); };
  virtual void VisitStringEntity(const StringEntity& node) { VisitTerminal(node); };
  virtual void VisitEscapeSequence(const EscapeSequence& node) { VisitStringEntity(node); };
  virtual void VisitString(const String& node) { VisitNonterminal(node); };
  virtual void VisitObject(const Object& node) { VisitNonterminal(node); };
  virtual void VisitField(const Field& node) { VisitNonterminal(node); };
  virtual void VisitPathElement(const PathElement& node) { VisitTerminal(node); };
  virtual void VisitPathEscape(const PathEscape& node) { VisitTerminal(node); };
  virtual void VisitPathSeparator(const PathSeparator& node) { VisitTerminal(node); };
  virtual void VisitOperator(const Operator& node) { VisitTerminal(node); };
  virtual void VisitPath(const Path& node) { VisitNonterminal(node); };
  virtual void VisitAddSub(const AddSub& node) { VisitNonterminal(node); };
};

}  // namespace shell::parser::ast

#endif  // SRC_DEVELOPER_SHELL_PARSER_AST_H_
