/*
 * Copyright 2024 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MPACT_CHERIOT__DEBUG_COMMAND_SHELL_H_
#define MPACT_CHERIOT__DEBUG_COMMAND_SHELL_H_

#include <cstdint>
#include <deque>
#include <fstream>
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/debug_command_shell_interface.h"
#include "re2/re2.h"

namespace mpact::sim::generic {
class DataBuffer;
}  // namespace mpact::sim::generic

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::generic::DebugCommandShellInterface;

// This class implements an interactive command shell for a set of cores
// simulated by the MPact simulator using the CoreDebugInterface.
class DebugCommandShell : public DebugCommandShellInterface {
 public:
  // Default constructor is deleted.
  DebugCommandShell();

  // Add core access to the system. All cores must be added before calling Run.
  void AddCore(const CoreAccess &core_access) override;
  void AddCores(const std::vector<CoreAccess> &core_access) override;

  // The run method is the command interpreter. It parses the command strings,
  // executes the corresponding commands, displays results and error messages.
  void Run(std::istream &is, std::ostream &os) override;

  // This adds a custom command to the command interpreter. Usage will be added
  // to the standard command usage. The callable will be called before the
  // standard commands are processed.
  void AddCommand(absl::string_view usage,
                  CommandFunction command_function) override;

  // This adds an action point at the given address with 'function' as the
  // action. The string 'name' is used to give it an identifier to use when
  // listed.
  absl::Status SetActionPoint(uint64_t address, std::string name,
                              absl::AnyInvocable<void(uint64_t, int)> function);

 private:
  // Struct to track action point information.
  struct ActionPointInfo {
    uint64_t address;
    int id;
    std::string name;
    bool is_enabled;
  };

  // Helper method for formatting single data buffer value.
  std::string FormatSingleDbValue(generic::DataBuffer *db,
                                  const std::string &format, int width,
                                  int index) const;
  // Helper method for formatting multiple data buffer values.
  std::string FormatAllDbValues(generic::DataBuffer *db,
                                const std::string &format, int width) const;
  // Helper method for writing single data buffer value.
  absl::Status WriteSingleValueToDb(absl::string_view str_value,
                                    generic::DataBuffer *db, std::string format,
                                    int width, int index) const;

  // Helper method for processing read memory command.
  std::string ReadMemory(int core, const std::string &str_value,
                         absl::string_view format);
  // Helper method for processing write memory command.
  std::string WriteMemory(int core, const std::string &str_value1,
                          const std::string &format,
                          const std::string &str_value2);
  // Helper method used to parse a numeric string or use the string as a
  // symbol name for lookup in the loader.
  absl::StatusOr<uint64_t> GetValueFromString(int core,
                                              const std::string &str_value,
                                              int radix);

  // Method to step over call instructions.
  absl::Status StepOverCall(int core, std::ostream &os);

  // Returns true if the given register name is a known capability register.
  bool IsCapabilityRegister(const std::string &reg_name) const;
  // Reads and formats a capability register.
  std::string FormatCapabilityRegister(int core,
                                       const std::string &reg_name) const;
  // Reads and formats a register.
  std::string FormatRegister(int core, const std::string &reg_name) const;
  // Reads and formats $all registers - stored in reg_vec_.
  std::string FormatAllRegisters(int core) const;

  // Action point handling.
  std::string ListActionPoints();
  std::string EnableActionPointN(const std::string &index_str);
  std::string DisableActionPointN(const std::string &index_str);
  std::string ClearActionPointN(const std::string &index_str);
  std::string ClearAllActionPoints();

  std::vector<CoreAccess> core_access_;
  // Help message displayed for command 'help'.
  std::string help_message_;

  // Regular expression variables used to parse commands in the shell.
  LazyRE2 quit_re_;
  LazyRE2 core_re_;
  // Run control commands.
  LazyRE2 run_re_;
  LazyRE2 run_free_re_;
  LazyRE2 wait_re_;
  LazyRE2 step_1_re_;
  LazyRE2 step_n_re_;
  LazyRE2 halt_re_;
  LazyRE2 next_re_;
  // Read/write registers.
  LazyRE2 read_reg_re_;
  LazyRE2 read_reg2_re_;
  LazyRE2 write_reg_re_;
  LazyRE2 rd_vreg_re_;
  LazyRE2 wr_vreg_re_;
  // Read/write memory commands.
  LazyRE2 read_mem_re_;
  LazyRE2 read_mem2_re_;
  LazyRE2 write_mem_re_;
  // Breakpoint commands.
  LazyRE2 set_break_re_;
  LazyRE2 set_break2_re_;
  LazyRE2 set_break_n_re_;
  LazyRE2 list_break_re_;
  LazyRE2 clear_break_n_re_;
  LazyRE2 clear_break_re_;
  LazyRE2 clear_all_break_re_;
  // Watch point commands.
  LazyRE2 set_watch_re_;
  LazyRE2 set_watch2_re_;
  LazyRE2 set_watch_n_re_;
  LazyRE2 list_watch_re_;
  LazyRE2 clear_watch_re_;
  LazyRE2 clear_watch_n_re_;
  LazyRE2 clear_all_watch_re_;
  // Action point commands.
  LazyRE2 list_action_re_;
  LazyRE2 enable_action_n_re_;
  LazyRE2 disable_action_n_re_;
  LazyRE2 clear_action_n_re_;
  LazyRE2 clear_all_action_re_;
  // Branch trace
  LazyRE2 branch_trace_re_;
  // Execute commands from a file.
  LazyRE2 exec_re_;
  // Empty command.
  LazyRE2 empty_re_;
  // Help command.
  LazyRE2 help_re_;

  int current_core_;
  uint8_t mem_buffer_[kMemBufferSize];
  uint8_t tag_buffer_[kMemBufferSize >> 3];
  std::vector<CommandFunction> command_functions_;
  std::vector<std::string> command_usage_;
  absl::flat_hash_set<std::string> capability_registers_;
  std::vector<std::string> reg_vector_;
  absl::flat_hash_set<std::string> exec_file_names_;
  std::deque<std::istream *> command_streams_;
  std::deque<std::string> previous_commands_;
  std::vector<absl::btree_map<int, ActionPointInfo>> core_action_point_info_;
  std::vector<int> core_action_point_id_;
};

}  // namespace cheriot
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_CHERIOT__DEBUG_COMMAND_SHELL_H_
