// 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.

#include "src/developer/shell/parser/parser.h"

#include "src/developer/shell/parser/ast.h"
#include "src/developer/shell/parser/combinators.h"
#include "src/developer/shell/parser/text_match.h"

namespace shell::parser {
namespace {

ParseResult Whitespace(ParseResult prefix);

// Create a parser that runs a sequence of parsers consecutively, with optional whitespace parsed
// between each parser.
fit::function<ParseResult(ParseResult)> WSSeq(fit::function<ParseResult(ParseResult)> first) {
  return Seq(Maybe(Whitespace), std::move(first), Maybe(Whitespace));
}

template <typename... Args>
fit::function<ParseResult(ParseResult)> WSSeq(fit::function<ParseResult(ParseResult)> first,
                                              Args... args) {
  return Seq(Maybe(Whitespace), std::move(first), WSSeq(std::move(args)...));
}

ParseResult IdentifierCharacter(ParseResult prefix);

// Parse a keyword.
template <typename T = ast::Terminal>
fit::function<ParseResult(ParseResult)> KW(const std::string& keyword) {
  return Seq(Token<T>(keyword), Not(IdentifierCharacter));
}

// Token Rules -------------------------------------------------------------------------------------

ParseResult IdentifierCharacter(ParseResult prefix) {
  return CharGroup("a-zA-Z0-9_")(std::move(prefix));
}

ParseResult Whitespace(ParseResult prefix) {
  return NT<ast::Whitespace>(
      OnePlus(Alt(AnyChar(" \n\r\t"), Seq(Token("#"), ZeroPlus(AnyCharBut("\n")), Token("\n")))))(
      std::move(prefix));
}

ParseResult Digit(ParseResult prefix) { return CharGroup("0-9")(std::move(prefix)); }

ParseResult HexDigit(ParseResult prefix) { return CharGroup("a-fA-F0-9")(std::move(prefix)); }

ParseResult UnescapedIdentifier(ParseResult prefix) {
  return Token<ast::UnescapedIdentifier>(OnePlus(IdentifierCharacter))(std::move(prefix));
}

ParseResult PathCharacter(ParseResult prefix) {
  return Seq(Not(Whitespace), AnyCharBut("`&;|/\\()[]{}"))(std::move(prefix));
}

ParseResult PathElement(ParseResult prefix) {
  return Alt(Token<ast::PathEscape>(Seq(Token("\\"), AnyChar)),
             Token<ast::PathElement>(OnePlus(PathCharacter)),
             Seq(Token<ast::PathEscape>("`"), Token<ast::PathElement>(ZeroPlus(AnyCharBut("`"))),
                 Token<ast::PathEscape>("`")))(std::move(prefix));
}

// Grammar Rules -----------------------------------------------------------------------------------

// Parses an identifier
//     myVariable
ParseResult Identifier(ParseResult prefix) {
  return NT<ast::Identifier>(Seq(Not(Digit), UnescapedIdentifier))(std::move(prefix));
}

// Parses a root path with at least one element and no trailing slash
//     /foo
//     /foo/bar
ParseResult RootPath(ParseResult prefix) {
  return OnePlus(Seq(Token<ast::PathSeparator>("/"), OnePlus(PathElement)))(std::move(prefix));
}

// Parses a path
//     /foo
//     /foo/bar
//     /foo/bar/
//     ./foo/bar/
//     ./
//     /
//     .
ParseResult Path(ParseResult prefix) {
  return NT<ast::Path>(Alt(Seq(Maybe(Token<ast::PathElement>(".")), RootPath, Maybe(Token("/"))),
                           Seq(Maybe(Token<ast::PathElement>(".")), Token<ast::PathSeparator>("/")),
                           Token<ast::PathElement>(".")))(std::move(prefix));
}

// Parses an unadorned decimal Integer
//     0
//     12345
//     12_345
ParseResult DecimalInteger(ParseResult prefix) {
  return Alt(
      Seq(Token<ast::DecimalGroup>("0"), Not(Digit)),
      Seq(Not(Token("0")), Token<ast::DecimalGroup>(OnePlus(Digit)),
          ZeroPlus(Seq(Token("_"), Token<ast::DecimalGroup>(OnePlus(Digit))))))(std::move(prefix));
}

// Parses a hexadecimal integer marked by '0x'
//     0x1234abcd
//     0x12_abcd
ParseResult HexInteger(ParseResult prefix) {
  return Seq(Token("0x"), Seq(Token<ast::HexGroup>(OnePlus(HexDigit)),
                              ZeroPlus(Seq(Token("_"), Token<ast::HexGroup>(OnePlus(HexDigit))))))(
      std::move(prefix));
}

// Parses an integer.
//     0
//     12345
//     12_345
//     0x1234abcd
//     0x12_abcd
ParseResult Integer(ParseResult prefix) {
  // TODO: Binary integers, once we ask the FIDL team about them.
  return NT<ast::Integer>(Alt(HexInteger, DecimalInteger))(std::move(prefix));
}

// Parse a Real (unimplemented).
ParseResult Real(ParseResult prefix) { return ParseResult::kEnd; }

// Parses an escape sequence.
//     \n
//     \r
//     \xF0
ParseResult EscapeSequence(ParseResult prefix) {
  return Alt(Token<ast::EscapeSequence>("\\n"), Token<ast::EscapeSequence>("\\t"),
             Token<ast::EscapeSequence>("\\\n"), Token<ast::EscapeSequence>("\\r"),
             Token<ast::EscapeSequence>("\\\\"), Token<ast::EscapeSequence>("\\\""),
             Token<ast::EscapeSequence>(
                 Seq(Token<ast::EscapeSequence>("\\u"), Multi(6, HexDigit))))(std::move(prefix));
}

// Parses a sequence of characters that might be within a string body.
//     The quick brown fox jumped over the lazy dog.
ParseResult StringEntity(ParseResult prefix) {
  return Alt(Token<ast::StringEntity>(OnePlus(AnyCharBut("\n\\\""))),
             EscapeSequence)(std::move(prefix));
}

// Parses an ordinary string literal.
//     "The quick brown fox jumped over the lazy dog."
//     "A newline.\nA tab\tA code point\xF0"
ParseResult NormalString(ParseResult prefix) {
  return NT<ast::String>(Seq(Token("\""), ZeroPlus(StringEntity), Token("\"")))(std::move(prefix));
}

// Parse an ordinary string literal, or a multiline string literal.
//     "The quick brown fox jumped over the lazy dog."
//     "A newline.\nA tab\tA code point\xF0"
// TODO: Decide on a MultiString syntax we like.
ParseResult String(ParseResult prefix) {
  // return Alt(NormalString, MultiString)(prefix);
  return NormalString(std::move(prefix));
}

// Parse an Atom (a simple literal value).
//     "The quick brown fox jumped over the lazy dog."
//     0x1234abcd
//     my_variable
//     3.2156
//     ./some/path
ParseResult Atom(ParseResult prefix) {
  return Alt(Identifier, String, Real, Integer, Path)(std::move(prefix));
}

ParseResult LogicalOr(ParseResult prefix);
const auto& SimpleExpression = LogicalOr;

// Parse a field in an object literal.
//     foo: 6
//     "bar & grill": "Open now"
ParseResult Field(ParseResult prefix) {
  return NT<ast::Field>(WSSeq(Alt(NormalString, Identifier), Token<ast::FieldSeparator>(":"),
                              SimpleExpression))(std::move(prefix));
}

// Parse the body of an object literal.
//     foo: 6
//     foo: 6, "bar & grill": "Open now",
ParseResult ObjectBody(ParseResult prefix) {
  return WSSeq(Field, ZeroPlus(WSSeq(Token(","), Field)), Maybe(Token(",")))(std::move(prefix));
}

// Parse an object literal.
//     {}
//     { foo: 6, "bar & grill": "Open now" }
//     { foo: { bar: 6 }, "bar & grill": "Open now" }
ParseResult Object(ParseResult prefix) {
  return NT<ast::Object>(WSSeq(Token("{"), Maybe(ObjectBody), Token("}")))(std::move(prefix));
}

// Parse a Value.
//     "The quick brown fox jumped over the lazy dog."
//     0x1234abcd
//     { foo: 3, bar: 6 }
ParseResult Value(ParseResult prefix) {
  /* Eventual full version of this rule is:
  return Alt(List, Object, Range, Lambda, Parenthetical, Block, If, Atom)(std::move(prefix));
  */
  return Alt(Object, Atom)(std::move(prefix));
}

// Unimplemented.
ParseResult Lookup(ParseResult prefix) { return Value(std::move(prefix)); }

// Unimplemented.
ParseResult Negate(ParseResult prefix) { return Lookup(std::move(prefix)); }

// Unimplemented.
ParseResult Mul(ParseResult prefix) { return Negate(std::move(prefix)); }

// Parse an addition expression.
//     2 + 2
ParseResult Add(ParseResult prefix) {
  return LAssoc<ast::AddSub>(Seq(Mul, Maybe(Whitespace)),
                             WSSeq(Token<ast::Operator>(AnyChar("+-")), Mul))(std::move(prefix));
}

// Unimplemented.
ParseResult Comparison(ParseResult prefix) { return Add(std::move(prefix)); }

// Unimplemented.
ParseResult LogicalNot(ParseResult prefix) { return Comparison(std::move(prefix)); }

// Unimplemented.
ParseResult LogicalAnd(ParseResult prefix) { return LogicalNot(std::move(prefix)); }

// Unimplemented.
ParseResult LogicalOr(ParseResult prefix) { return LogicalAnd(std::move(prefix)); }

// Parses an expression. This is effectively unimplemented right now.
ParseResult Expression(ParseResult prefix) {
  // Unimplemented
  return NT<ast::Expression>(SimpleExpression)(std::move(prefix));
}

// Parses a variable declaration:
//     var foo = 4.5
//     const foo = "Ham sandwich"
ParseResult VariableDecl(ParseResult prefix) {
  return NT<ast::VariableDecl>(WSSeq(Alt(KW<ast::Var>("var"), KW<ast::Const>("const")), Identifier,
                                     Token("="), Expression))(std::move(prefix));
}

// Parses the body of a program, but doesn't create an AST node. This is useful because the rule is
// recursive, but we want to flatten its structure.
ParseResult ProgramContent(ParseResult prefix) {
  /* Eventual full version of this rule is:
  return Alt(WSSeq(VariableDecl, Maybe(WSSeq(AnyChar(";&", "; or &"), ProgramMeta))),
             WSSeq(FunctionDecl, Program),
             WSSeq(Expression, Maybe(WSSeq(AnyChar(";&", "; or &"), ProgramMeta))),
  Empty)(prefix);
  */
  return Alt(WSSeq(VariableDecl, Maybe(WSSeq(AnyChar(";&"), ProgramContent))),
             Empty)(std::move(prefix));
}

}  // namespace

std::shared_ptr<ast::Node> Parse(std::string_view text) {
  if (auto res = NT<ast::Program>(Seq(ProgramContent, EOS))(ParseResult(text))) {
    return res.node();
  }

  return nullptr;
}

}  // namespace shell::parser
