// Copyright 2019 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/console/command.h"

#include <lib/syslog/cpp/macros.h>
#include <stdlib.h>

#include <regex>
#include <sstream>
#include <string_view>
#include <vector>

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

namespace shell::console {

Command::Command() = default;

Command::~Command() = default;

namespace {

// Walk a parse tree for errors and collect their messages into the given output stringstream.
void CollectErrors(const parser::ast::Node& node, std::stringstream* out) {
  if (auto err = node.AsError()) {
    if (out->tellp() > 0) {
      (*out) << "\n";
    }

    (*out) << err->message();
  } else {
    for (const auto& child : node.Children()) {
      CollectErrors(*child, out);
    }
  }
}

// Walk a parse tree for errors and collect their messages.
std::string CollectErrors(const parser::ast::Node& node) {
  std::stringstream out;
  CollectErrors(node, &out);
  return out.str();
}

// Visitor for loading a parser AST into a FIDL AST.
class NodeASTVisitor : public parser::ast::NodeVisitor {
 public:
  explicit NodeASTVisitor(AstBuilder* builder) : builder_(builder) {}
  AstBuilder::NodeId id() const { return id_; }

  void VisitNode(const parser::ast::Node& node) override {
    FX_NOTREACHED() << "Parser produced unknown node type.";
  }

  void VisitProgram(const parser::ast::Program& node) override {
    // TODO: Multiple statements.
    for (const auto& child : node.Children()) {
      if (auto ch = child->AsVariableDecl()) {
        return VisitVariableDecl(*ch);
      }
    }

    FX_NOTREACHED();
  }

  void VisitVariableDecl(const parser::ast::VariableDecl& node) override {
    node.expression()->Visit(this);
    id_ = builder_->AddVariableDeclaration(node.identifier(), std::move(type_), id_, false);
  }

  void VisitInteger(const parser::ast::Integer& node) override {
    id_ = builder_->AddIntegerLiteral(node.value());
    llcpp::fuchsia::shell::BuiltinType type = llcpp::fuchsia::shell::BuiltinType::INTEGER;
    llcpp::fuchsia::shell::BuiltinType* type_ptr = builder_->ManageCopyOf(&type);
    type_ = llcpp::fuchsia::shell::ShellType::WithBuiltinType(fidl::unowned_ptr(type_ptr));
  }

  void VisitIdentifier(const parser::ast::Identifier& node) override {
    FX_NOTREACHED() << "Variable fetches are unimplemented." << node.identifier();
  }

  void VisitPath(const parser::ast::Path& node) override {
    FX_NOTREACHED() << "Paths are unimplemented.";
  }

  void VisitAddSub(const parser::ast::AddSub& node) override {
    FX_DCHECK(node.type() == parser::ast::AddSub::kAdd) << "Subtraction is unimplemented.";
    node.a()->Visit(this);
    AstBuilder::NodeId a_id = id_;
    node.b()->Visit(this);
    AstBuilder::NodeId b_id = id_;
    // type_ is now from b, and we leak it on purpose
    id_ = builder_->AddAddition(/*with_exceptions=*/false, a_id, b_id);
  }

  void VisitExpression(const parser::ast::Expression& node) override {
    FX_DCHECK(node.Children().size() > 0);
    node.Children()[0]->Visit(this);
  }

  void VisitString(const parser::ast::String& node) override {
    id_ = builder_->AddStringLiteral(node.value());
    llcpp::fuchsia::shell::BuiltinType type = llcpp::fuchsia::shell::BuiltinType::STRING;
    llcpp::fuchsia::shell::BuiltinType* type_ptr = builder_->ManageCopyOf(&type);
    type_ = llcpp::fuchsia::shell::ShellType::WithBuiltinType(fidl::unowned_ptr(type_ptr));
  }

  void VisitObject(const parser::ast::Object& node) override {
    builder_->OpenObject();

    for (const auto& field : node.fields()) {
      field->Visit(this);
    }

    auto result = builder_->CloseObject();
    id_ = result.value_node;

    llcpp::fuchsia::shell::NodeId id;
    id = result.schema_node;
    llcpp::fuchsia::shell::NodeId* id_ptr = builder_->ManageCopyOf(&id);
    type_ = llcpp::fuchsia::shell::ShellType::WithObjectSchema(fidl::unowned_ptr(id_ptr));
  }

  void VisitField(const parser::ast::Field& node) override {
    node.value()->Visit(this);
    builder_->AddField(node.name(), id_, std::move(type_));
  }

 private:
  AstBuilder* builder_;
  AstBuilder::NodeId id_;
  llcpp::fuchsia::shell::ShellType type_;
};

}  // namespace

bool Command::Parse(const std::string& line) {
  if (line.empty()) {
    return true;
  }

  auto node = parser::Parse(line);

  if (node->HasErrors()) {
    parse_error_ = Err(ErrorType::kBadParse, CollectErrors(*node));
    return false;
  }

  auto program = node->AsProgram();
  FX_DCHECK(program) << "Parse did not yield a program node!";

  // TODO: Change the file ID to something useful.
  AstBuilder builder(1);
  NodeASTVisitor visitor(&builder);
  program->Visit(&visitor);
  builder.SetRoot(visitor.id());
  accumulated_nodes_ = std::move(builder);

  return true;
}

}  // namespace shell::console
