// 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_SIM_GENERIC_ACTION_POINT_MANAGER_BASE_H_
#define MPACT_SIM_GENERIC_ACTION_POINT_MANAGER_BASE_H_

#include <cstdint>
#include <utility>

#include "absl/container/btree_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"

namespace mpact::sim::generic {

// This file defines the ActionPointManager base class which provides the low
// level functionality required to implement breakpoints and other 'actions'
// that need to be performed when an instruction executes. It relies on the
// presence of a software breakpoint instruction in the program to stop
// execution. A handler will check whether an executed software breakpoint
// instruction is due to an action point, or if it is part of a program. If it
// is an action point, the handler will call into this class to execute all
// enabled action points at that address.
//
// The ebreak is only written to memory if there is at least one enabled action
// and is replaced with the original instruction when all actions are disabled.

// The ActionPointManagerBase class depends on an interface to read/write
// appropriate software interrupt instructions to memory, e.g., ebreak for the
// RiscV ISA. This class defines the interface to that class. Instances of this
// class must be able to replace the instruction at the given address with a
// breakpoint instruction, save the original instruction, and then restore it
// when requested. The ActionPointMemoryInterface must also invalidate any
// cached decoding of the instruction at the given address, so the next use of
// the instruction will be decoded with the most recent version stored to
// memory. Each ISA should derive an appropriate implementation of this class.
class ActionPointMemoryInterface {
 public:
  virtual ~ActionPointMemoryInterface() = default;
  // This restores the original instruction in memory, and allows it to be
  // decoded and executed, provided the address is an action point. If not,
  // no action is taken.
  virtual absl::Status WriteOriginalInstruction(uint64_t address) = 0;
  // Store breakpoint instruction, provided the address is an action point.
  // Otherwise no action is taken.
  virtual absl::Status WriteBreakpointInstruction(uint64_t address) = 0;
};

class ActionPointManagerBase {
 public:
  // Function type for actions - void function that takes a 64 bit address.
  using ActionFcn = absl::AnyInvocable<void(uint64_t address, int id)>;

  // The constructor takes an instance of the ActionPointMemoryInterface class.
  ActionPointManagerBase(ActionPointMemoryInterface *ap_mem_interface);
  virtual ~ActionPointManagerBase();

  // Returns true if the given address has an action point, regardless of
  // whether it is active or not.
  bool HasActionPoint(uint64_t address) const;
  // Set action_fcn to be executed when reaching address. There may be multiple
  // actions on an instruction so an id is returned on successfully setting an
  // action point.
  absl::StatusOr<int> SetAction(uint64_t address, ActionFcn action_fcn);
  // Remove the action point with the given id.
  absl::Status ClearAction(uint64_t address, int id);
  // Enable/Disable the action point with the given id.
  absl::Status EnableAction(uint64_t address, int id);
  absl::Status DisableAction(uint64_t address, int id);
  // Return true if there is at least one enabled 'action' at this address.
  bool IsActionPointActive(uint64_t address) const;
  // Return true if the given 'action' is enabled.
  bool IsActionEnabled(uint64_t address, int id) const;
  // Remove all action points.
  void ClearAllActionPoints();
  // Perform all enabled actions for the given address. If address is not an
  // action point, not action is performed.
  void PerformActions(uint64_t address);

  // Accessor.
  ActionPointMemoryInterface *ap_memory_interface() const {
    return ap_memory_interface_;
  }

 private:
  // Struct to store information about an individual 'action'. It contains a
  // callable and a flag that indicates whether the action is enabled or not.
  struct ActionInfo {
    ActionFcn action_fcn;
    bool is_enabled;
    ActionInfo(ActionFcn action_fcn, bool is_enabled)
        : action_fcn(::std::move(action_fcn)), is_enabled(is_enabled) {}
  };

  struct ActionPointInfo {
    // Address of the action point.
    uint64_t address;
    // Id to use for the next added 'action'.
    int next_id = 0;
    // Number of 'actions' that are enabled.
    int num_active = 0;
    // Map from id to action function struct.
    absl::btree_map<int, ActionInfo *> action_map;
    ActionPointInfo(uint64_t address) : address(address) {}
  };

  // Interface to program memory.
  ActionPointMemoryInterface *ap_memory_interface_;
  // Map from address to action info struct.
  absl::btree_map<uint64_t, ActionPointInfo *> action_point_map_;
};

}  // namespace mpact::sim::generic

#endif  // MPACT_SIM_GENERIC_ACTION_POINT_MANAGER_BASE_H_
