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

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_

#include <optional>

#include "src/developer/debug/zxdb/client/function_return_info.h"
#include "src/developer/debug/zxdb/client/step_mode.h"
#include "src/developer/debug/zxdb/client/step_thread_controller.h"
#include "src/developer/debug/zxdb/client/thread_controller.h"
#include "src/developer/debug/zxdb/common/address_ranges.h"
#include "src/developer/debug/zxdb/symbols/file_line.h"

namespace zxdb {

class StepOverThreadController;
class StepThreadController;

// Implements a user-level "step into" command. On top of the regular step into, this provides
// an option to skip function prologues.
//
// Function prologues are the code at the beginning of a function that sets up the stack frame,
// and function parameters and backtraces might not be correct in this address range. Therefore,
// we usually want to step through this prologue when stepping into a new function so that the
// state is valid when the user inspects it.
class StepIntoThreadController : public ThreadController {
 public:
  // Constructor for kSourceLine and kInstruction modes. It will initialize itself to the thread's
  // current position when the thread is attached.
  //
  // The function_return callback (if supplied) will be issued when the "step into" terminates with
  // the completion of the function.
  explicit StepIntoThreadController(StepMode mode, FunctionReturnCallback function_return = {});

  // Steps given the source file/line.
  explicit StepIntoThreadController(const FileLine& line,
                                    FunctionReturnCallback function_return = {});

  // Constructor for a kAddressRange mode (the mode is implicit). Continues execution as long as the
  // IP is in range.
  explicit StepIntoThreadController(AddressRanges ranges,
                                    FunctionReturnCallback function_return = {});

  ~StepIntoThreadController() override;

  // Controls whether this class skips function prologues that it might step into. See class
  // comment above. Defaults to true.
  bool should_skip_prologue() const { return should_skip_prologue_; }
  void set_should_skip_prologue(bool skip) { should_skip_prologue_ = skip; }

  // ThreadController implementation.
  void InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) override;
  ContinueOp GetContinueOp() override;
  StopOp OnThreadStop(debug_ipc::ExceptionType stop_type,
                      const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override;
  const char* GetName() const override { return "Step Into"; }

 private:
  bool should_skip_prologue_ = true;

  FrameFingerprint original_frame_fingerprint_;

  std::unique_ptr<StepThreadController> step_into_;
  std::unique_ptr<StepOverThreadController> skip_prologue_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_STEP_INTO_THREAD_CONTROLLER_H_
