// 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 "repl.h"

#include <stdio.h>
#include <string.h>

#include <cctype>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <vector>

namespace shell::repl {

Repl::Repl(JSContext* ctx, const std::string& prompt)
    : li_([this](const std::string& s) { HandleLine(s); }, prompt),
      ctx_(ctx),
      output_(&std::cout),
      exit_shell_cmd_(false),
      running_(false) {
  Write("Type \\h for help\n");
  li_.SetAutocompleteCallback([this](std::string line_to_complete) {
    this->line_to_complete_ = line_to_complete;
    std::string script = "repl.autocompletionCallback();";
    JSValue completions_as_js_str =
        JS_Eval(ctx_, script.c_str(), script.length(), "<evalScript>", JS_EVAL_TYPE_GLOBAL);
    const char* completions_as_cstr = JS_ToCString(ctx_, completions_as_js_str);
    if (!completions_as_cstr) {  // completion error, return an empty vector
      return std::vector<std::string>();
    }
    std::string completions_as_str(completions_as_cstr);
    std::vector<std::string> completions;
    std::stringstream completions_as_stream(completions_as_str);
    std::string cur_completion;
    while (std::getline(completions_as_stream, cur_completion, '/')) {
      completions.push_back(line_to_complete + cur_completion);
    }
    return completions;
  });
  li_.Show();
}

Repl::Repl(JSContext* ctx, const std::string& prompt, fit::function<void(const std::string&)> cb)
    : li_(std::move(cb), prompt),
      ctx_(ctx),
      output_(&std::cout),
      exit_shell_cmd_(false),
      running_(false) {
  Write("Type \\h for help\n");
  li_.Show();
}

void Repl::Write(const char* output) { *output_ << output; }
void Repl::ChangeOutput(std::ostream* ss) { output_ = ss; }

void Repl::ShowPrompt() {
  running_ = false;
  li_.Show();
}

const char* Repl::GetCmd() { return cur_cmd_.c_str(); }

const char* Repl::GetLine() { return line_to_complete_.c_str(); }

bool Repl::FeedInput(uint8_t* bytes, size_t num_bytes) {
  if (running_) {
    if (num_bytes >= 1 &&
        bytes[0] == 26) {  // shell cmd 'c' to show the prompt in spite of running_
      ShowPrompt();
    }
    return false;
  }
  for (size_t i = 0; i < num_bytes; i++) {
    li_.OnInput(static_cast<char>(bytes[i]));
    if (exit_shell_cmd_) {
      return true;
    }
    if (running_) {  // cmd is still running, we discard the rest of the input
      return false;
    }
  }
  return false;
}

void Repl::HandleLine(const std::string& line) {
  li_.Hide();
  running_ = true;
  std::string cmd = mexpr_ + line;
  std::string shell_cmd = GetAndExecuteShellCmd(cmd);
  if (shell_cmd == "\\q") {
    exit_shell_cmd_ = true;
  } else if (!shell_cmd.empty()) {
    mexpr_ = "";
    exit_shell_cmd_ = false;
    ShowPrompt();
  } else {
    std::string open_symbols = OpenSymbols(cmd);
    if (open_symbols.empty()) {
      mexpr_ = "";
      li_.AddToHistory(cmd);
      EvalCmd(cmd);
    } else {
      mexpr_ = cmd;
      ShowPrompt();
    }
    exit_shell_cmd_ = false;
  }
}

std::string Repl::GetAndExecuteShellCmd(std::string cmd) {
  if (cmd.substr(0, 2) == "\\h") {
    std::string help_msg =
        "\\q\texit\n"
        "\\h\tthis help\n"
        "Ctrl-Z\tmake the (hidden) prompt show up when a previous command aborted with an error\n";
    Write(help_msg.c_str());
    return cmd.substr(0, 2);
  }
  if (cmd.substr(0, 2) == "\\q") {
    return cmd.substr(0, 2);
  }
  return "";
}

void Repl::EvalCmd(const std::string& cmd) {
  cur_cmd_ = cmd;  // saving the cmd in the Repl class instance, to be executed through a JS call
  std::string script = "repl.evalScriptAwaitsPromise()";
  JSValue res = JS_Eval(ctx_, script.c_str(), script.length(), "<evalScript>", JS_EVAL_TYPE_GLOBAL);
  if (JS_IsException(res)) {  // the script above was at fault, that's bad
    js_std_dump_error(ctx_);
    ShowPrompt();
  }
}

bool match(char a, char b) {
  if (a == '(' && b == ')') {
    return true;
  }
  if (a == '{' && b == '}') {
    return true;
  }
  if (a == '[' && b == ']')
    return true;
  return false;
}

bool isIdentifierAllowed(char c) {
  return std::isalpha(c) || std::isdigit(c) || c == '_' || c == '$';
}

std::string Repl::OpenSymbols(const std::string& cmd) {
  std::string open_symbols;
  bool regex_possible = true;
  size_t n = cmd.length();
  size_t i = 0;
  while (i < n) {
    if (cmd[i] == '\'' || cmd[i] == '\"' || cmd[i] == '`') {  // string
      char delim = cmd[i];
      open_symbols.push_back(delim);
      i++;
      while (i < n) {
        if (cmd[i] == '\\')
          i++;
        else if (cmd[i] == delim) {
          open_symbols.pop_back();
          i++;
          break;
        }
        i++;
      }
      regex_possible = false;
    }

    else if (cmd[i] == '/') {
      if (cmd[i + 1] == '*') {  // block comment
        std::size_t ip = cmd.find("*/", i + 1);
        if (ip != std::string::npos)
          i = ip + 1;
        else {
          open_symbols.push_back('*');
          i = n;
        }
      } else if (cmd[i + 1] == '/') {  // line comment
        for (i += 2; i < n; i++) {
          if (cmd[i] == '\n')
            break;
        }
        i++;
      } else if (regex_possible) {  // regex
        open_symbols.push_back('/');
        for (i++; i < n; i++) {
          if (cmd[i] == '\\') {
            if (i < n)
              i++;
          } else if (open_symbols.back() == '[') {  // ignore / or [ if within []
            if (cmd[i] == ']')
              open_symbols.pop_back();
          } else if (cmd[i] == '[') {
            open_symbols.push_back('[');
            if (cmd[i] == '[' || cmd[i] == ']')
              i++;
          } else if (cmd[i] == '/') {
            open_symbols.pop_back();
            break;
          }
        }
        i++;
        regex_possible = false;
      } else {
        regex_possible = true;
        i++;
      }
    }

    else if (strchr("{[(", cmd[i])) {
      open_symbols.push_back(cmd[i]);
      regex_possible = true;
      i++;
    }

    else if (strchr("}])", cmd[i])) {
      regex_possible = false;
      if (match(open_symbols.back(), cmd[i]) && !open_symbols.empty()) {
        open_symbols.pop_back();
      }
      i++;
    }

    else if (std::isspace(cmd[i])) {
      i++;
    }

    else if (strchr("+-", cmd[i])) {
      regex_possible = true;
      i++;
    }

    else if (std::isdigit(cmd[i])) {  // a number
      while (i < n && (std::isalnum(cmd[i]) || cmd[i] == '.' || cmd[i] == '+' || cmd[i] == '-')) {
        i++;
      }
    }

    else if (isIdentifierAllowed(cmd[i])) {  // an identifier
      regex_possible = true;
      int old_i = i;
      i++;
      while (i < n && isIdentifierAllowed(cmd[i])) {
        i++;
      }
      std::set<std::string> no_regex_keywords = {
          "this", "super", "undefined", "null", "true", "false", "Infinity", "NaN", "arguments"};
      std::set<std::string> keywords = {
          "break",      "case",      "catch",    "continue",   "debugger",  "default",   "delete",
          "do",         "else",      "finally",  "for",        "function",  "if",        "in",
          "instanceof", "new",       "return",   "switch",     "this",      "throw",     "try",
          "typeof",     "while",     "with",     "class",      "const",     "enum",      "import",
          "export",     "extends",   "super",    "implements", "interface", "let",       "package",
          "private",    "protected", "public",   "static",     "yield",     "undefined", "null",
          "true",       "false",     "Infinity", "NaN",        "eval",      "arguments", "await",
          "void",       "var"};
      if (keywords.count(cmd.substr(old_i, i - old_i)) > 0) {
        if (no_regex_keywords.count(cmd.substr(old_i, i - old_i)) > 0) {
          regex_possible = false;
        }
        continue;
      }
      size_t ip = i;
      while (ip < n && std::isspace(cmd[ip])) {
        ip++;
      }
      if (ip < n && cmd[ip] == '(') {  // beginning of function, regex possible
        continue;
      }
      regex_possible = false;
    } else {
      regex_possible = true;
      i++;
    }
  }
  return open_symbols;
}

}  // namespace shell::repl
