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

#include "src/developer/debug/zxdb/client/until_thread_controller.h"

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

#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/breakpoint_settings.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/system.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/symbols/input_location.h"

namespace zxdb {

UntilThreadController::UntilThreadController(std::vector<InputLocation> locations)
    : ThreadController(), locations_(std::move(locations)), weak_factory_(this) {}

UntilThreadController::UntilThreadController(std::vector<InputLocation> locations,
                                             FrameFingerprint newest_frame, FrameComparison cmp)
    : ThreadController(),
      locations_(std::move(locations)),
      threshold_frame_(newest_frame),
      comparison_(cmp),
      weak_factory_(this) {}

UntilThreadController::~UntilThreadController() {
  if (breakpoint_)
    GetSystem()->DeleteBreakpoint(breakpoint_.get());
}

void UntilThreadController::InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) {
  SetThread(thread);

  BreakpointSettings settings;
  settings.scope = ExecutionScope(thread);
  settings.locations = std::move(locations_);

  // Frame-tied triggers can't be one-shot because we need to check the stack every time it
  // triggers. In the non-frame case the one-shot breakpoint will be slightly more efficient.
  settings.one_shot = !threshold_frame_.is_valid();

  breakpoint_ = GetSystem()->CreateNewInternalBreakpoint()->GetWeakPtr();
  breakpoint_->SetSettings(settings);

  if (breakpoint_->GetLocations().empty()) {
    // Setting the breakpoint may have resolved to no locations and the breakpoint is now pending.
    // For "until" this is not good because if the user does "until SomethingNonexistant" they would
    // like to see the error rather than have the thread transparently continue without stopping.
    cb(Err("Destination to run until matched no location."));
  } else {
    cb(Err());
  }
}

ThreadController::ContinueOp UntilThreadController::GetContinueOp() {
  // Stopping the thread is done via a breakpoint, so the thread can always be resumed with no
  // qualifications.
  return ContinueOp::Continue();
}

ThreadController::StopOp UntilThreadController::OnThreadStop(
    debug_ipc::ExceptionType stop_type,
    const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) {
  // Other controllers such as the StepOverRangeThreadController can use this as a sub-controller.
  // If the controllers don't care about breakpoint set failures, they may start using the thread
  // right away without waiting for the callback in InitWithThread() to asynchronously complete
  // (indicating the breakpoint was set successful).
  //
  // This is generally fine, we just need to be careful not to do anything in OnBreakpointSet() that
  // the code in this function depends on.
  if (!breakpoint_) {
    // Our internal breakpoint shouldn't be deleted out from under ourselves.
    FX_NOTREACHED();
    return kUnexpected;
  }

  // Only care about stops if one of the breakpoints hit was ours. Don't check the stop_type since
  // as long as the breakpoint was hit, we don't care how the program got there (it could have
  // single-stepped to the breakpoint).
  Breakpoint* our_breakpoint = breakpoint_.get();
  bool is_our_breakpoint = true;
  for (auto& hit : hit_breakpoints) {
    if (hit && hit.get() == our_breakpoint) {
      is_our_breakpoint = true;
      break;
    }
  }
  if (!is_our_breakpoint) {
    Log("Not our breakpoint.");
    return kUnexpected;
  }

  if (!threshold_frame_.is_valid()) {
    Log("No frame check required.");
    return kStopDone;
  }

  const Stack& stack = thread()->GetStack();
  if (stack.empty()) {
    FX_NOTREACHED();  // Should always have a current frame on stop.
    return kUnexpected;
  }

  // If inline frames are ambiguous and the one we want is one of the ambiguous ones, use it.
  if (comparison_ == kRunUntilEqualOrOlderFrame)
    SetInlineFrameIfAmbiguous(InlineFrameIs::kEqual, threshold_frame_);
  else
    SetInlineFrameIfAmbiguous(InlineFrameIs::kOneBefore, threshold_frame_);

  // Check frames.
  FrameFingerprint current_frame = stack.GetFrameFingerprint(0);
  if (FrameFingerprint::Newer(current_frame, threshold_frame_)) {
    Log("In newer frame, ignoring.");
    return kContinue;
  }
  if (comparison_ == kRunUntilOlderFrame && current_frame == threshold_frame_) {
    // In kRunUntilOlderFrame mode, the threshold frame fingerprint itself is one that should
    // continue running.
    Log("In threshold frame, ignoring.");
    return kContinue;
  }
  Log("Found target frame (or older).");
  return kStopDone;
}

System* UntilThreadController::GetSystem() { return &thread()->session()->system(); }

Target* UntilThreadController::GetTarget() { return thread()->GetProcess()->GetTarget(); }

}  // namespace zxdb
