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

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

#include <iostream>
#include <limits>

#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/shared/zx_status.h"
#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/frame_impl.h"
#include "src/developer/debug/zxdb/client/process_impl.h"
#include "src/developer/debug/zxdb/client/remote_api.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/developer/debug/zxdb/client/target_impl.h"
#include "src/developer/debug/zxdb/client/thread_controller.h"
#include "src/developer/debug/zxdb/symbols/process_symbols.h"

namespace zxdb {

ThreadImpl::ThreadImpl(ProcessImpl* process, const debug_ipc::ThreadRecord& record)
    : Thread(process->session()),
      process_(process),
      koid_(record.id.thread),
      stack_(this),
      weak_factory_(this) {
  SetMetadata(record);
  settings_.set_fallback(&process_->target()->settings());
}

ThreadImpl::~ThreadImpl() = default;

Process* ThreadImpl::GetProcess() const { return process_; }

uint64_t ThreadImpl::GetKoid() const { return koid_; }

const std::string& ThreadImpl::GetName() const { return name_; }

debug_ipc::ThreadRecord::State ThreadImpl::GetState() const { return state_; }
debug_ipc::ThreadRecord::BlockedReason ThreadImpl::GetBlockedReason() const {
  return blocked_reason_;
}

void ThreadImpl::Pause(fit::callback<void()> on_paused) {
  // The frames may have been requested when the thread was running which will have marked them
  // "empty but complete." When a pause happens the frames will become available so we want
  // subsequent requests to request them.
  ClearFrames();

  debug_ipc::PauseRequest request;
  request.id = {.process = process_->GetKoid(), .thread = koid_};
  session()->remote_api()->Pause(
      request, [weak_thread = weak_factory_.GetWeakPtr(), on_paused = std::move(on_paused)](
                   const Err& err, debug_ipc::PauseReply reply) mutable {
        if (!err.has_error() && weak_thread) {
          // Save the new metadata.
          if (reply.threads.size() == 1 && reply.threads[0].id.thread == weak_thread->koid_) {
            weak_thread->SetMetadata(reply.threads[0]);
          } else {
            // If the client thread still exists, the agent's record of that thread should have
            // existed at the time the message was sent so there should be no reason the update
            // doesn't match.
            FX_NOTREACHED();
          }
        }
        on_paused();
      });
}

void ThreadImpl::Continue(bool forward_exception) {
  debug_ipc::ResumeRequest request;
  request.ids.push_back({.process = process_->GetKoid(), .thread = koid_});

  if (controllers_.empty()) {
    request.how = forward_exception ? debug_ipc::ResumeRequest::How::kForwardAndContinue
                                    : debug_ipc::ResumeRequest::How::kResolveAndContinue;
  } else {
    // When there are thread controllers, ask the most recent one for how to continue.
    //
    // Theoretically we're running with all controllers at once and we want to stop at the first one
    // that triggers, which means we want to compute the most restrictive intersection of all of
    // them.
    //
    // This is annoying to implement and it's difficult to construct a situation where this would be
    // required. The controller that doesn't involve breakpoints is "step in range" and generally
    // ranges refer to code lines that will align. Things like "until" are implemented with
    // breakpoints so can overlap arbitrarily with other operations with no problem.
    //
    // A case where this might show up:
    //  1. Do "step into" which steps through a range of instructions.
    //  2. In the middle of that range is a breakpoint that's hit.
    //  3. The user does "finish." We'll ask the finish controller what to do and it will say
    //     "continue" and the range from step 1 is lost.
    // However, in this case probably does want to end up one stack frame back rather than several
    // instructions after the breakpoint due to the original "step into" command, so even when
    // "wrong" this current behavior isn't necessarily bad.
    controllers_.back()->Log("Continuing with this controller as primary.");
    ThreadController::ContinueOp op = controllers_.back()->GetContinueOp();
    if (op.synthetic_stop_) {
      // Synthetic stop. Skip notifying the backend and broadcast a stop notification for the
      // current state.
      controllers_.back()->Log("Synthetic stop.");
      debug_ipc::MessageLoop::Current()->PostTask(
          FROM_HERE, [thread = weak_factory_.GetWeakPtr()]() {
            if (thread) {
              StopInfo info;
              info.exception_type = debug_ipc::ExceptionType::kSynthetic;
              thread->OnException(info);
            }
          });
      return;
    } else {
      // Dispatch the continuation message.
      request.how = op.how;
      request.range_begin = op.range.begin();
      request.range_end = op.range.end();
    }
  }

  ClearFrames();
  session()->remote_api()->Resume(request, [](const Err& err, debug_ipc::ResumeReply) {});
}

void ThreadImpl::ContinueWith(std::unique_ptr<ThreadController> controller,
                              fit::callback<void(const Err&)> on_continue) {
  ThreadController* controller_ptr = controller.get();

  // Add it first so that its presence will be noted by anything its initialization function does.
  controllers_.push_back(std::move(controller));

  controller_ptr->InitWithThread(
      this, [this, controller_ptr, on_continue = std::move(on_continue)](const Err& err) mutable {
        if (err.has_error()) {
          controller_ptr->Log("InitWithThread failed.");
          NotifyControllerDone(controller_ptr);  // Remove the controller.
        } else {
          controller_ptr->Log("Initialized, continuing...");
          Continue(false);
        }
        on_continue(err);
      });
}

void ThreadImpl::AddPostStopTask(PostStopTask task) {
  // This function must only be called from a ThreadController::OnThreadStop() handler.
  FX_DCHECK(handling_on_stop_);
  post_stop_tasks_.push_back(std::move(task));
}

void ThreadImpl::JumpTo(uint64_t new_address, fit::callback<void(const Err&)> cb) {
  // The register to set.
  debug_ipc::WriteRegistersRequest request;
  request.id = {.process = process_->GetKoid(), .thread = koid_};
  request.registers.emplace_back(
      GetSpecialRegisterID(session()->arch(), debug_ipc::SpecialRegisterType::kIP), new_address);

  // The "jump" command updates the thread's location so we need to recompute the stack. So once the
  // jump is complete we re-request the thread's status.
  //
  // This could be made faster by requesting status immediately after sending the update so we don't
  // have to wait for two round-trips, but that complicates the callback logic and this feature is
  // not performance- sensitive.
  //
  // Another approach is to make the register request message able to optionally request a stack
  // backtrace and include that in the reply.
  session()->remote_api()->WriteRegisters(
      request, [thread = weak_factory_.GetWeakPtr(), cb = std::move(cb)](
                   const Err& err, debug_ipc::WriteRegistersReply reply) mutable {
        if (err.has_error()) {
          cb(err);  // Transport error.
        } else if (reply.status.has_error()) {
          cb(Err("Could not set thread instruction pointer: " + reply.status.message()));
        } else if (!thread) {
          cb(Err("Thread destroyed."));
        } else {
          // Success, update the current stack before issuing the callback.
          thread->SyncFramesForStack(std::move(cb));
        }
      });
}

void ThreadImpl::NotifyControllerDone(ThreadController* controller) {
  controller->Log("Controller done, removing.");

  // We expect to have few controllers so brute-force is sufficient.
  for (auto cur = controllers_.begin(); cur != controllers_.end(); ++cur) {
    if (cur->get() == controller) {
      controllers_.erase(cur);
      return;
    }
  }
  FX_NOTREACHED();  // Notification for unknown controller.
}

void ThreadImpl::StepInstruction() {
  debug_ipc::ResumeRequest request;
  request.ids.push_back({.process = process_->GetKoid(), .thread = koid_});
  request.how = debug_ipc::ResumeRequest::How::kStepInstruction;
  session()->remote_api()->Resume(request, [](const Err& err, debug_ipc::ResumeReply) {});
}

const Stack& ThreadImpl::GetStack() const { return stack_; }

Stack& ThreadImpl::GetStack() { return stack_; }

void ThreadImpl::SetMetadata(const debug_ipc::ThreadRecord& record) {
  FX_DCHECK(koid_ == record.id.thread);

  name_ = record.name;
  state_ = record.state;
  blocked_reason_ = record.blocked_reason;

  stack_.SetFrames(record.stack_amount, record.frames);
}

void ThreadImpl::OnException(const StopInfo& info) {
  if (settings().GetBool(ClientSettings::Thread::kDebugStepping)) {
    printf("----------\r\nGot %s exception @ 0x%" PRIx64 " in %s\r\n",
           debug_ipc::ExceptionTypeToString(info.exception_type), stack_[0]->GetAddress(),
           ThreadController::FrameFunctionNameForLog(stack_[0]).c_str());
  }

  if (stack_.empty()) {
    // Threads can stop with no stack if the thread is killed while processing an exception. If
    // this happens (or any other error that might cause an empty stack), declare all thread
    // controllers done since they can't meaningfully continue or process this state, and forcing
    // them all to separately check for an empty stack is error-prone.
    controllers_.clear();
  }

  // Debug tracking for proper usage from OnThreadStop handlers.
  handling_on_stop_ = true;

  // When any controller says "stop" it takes precedence and the thread will stop no matter what
  // any other controllers say.
  bool should_stop = false;

  // Set when any controller says "continue". If no controller says "stop" we need to differentiate
  // the case where there are no controllers or all controllers say "unexpected" (thread should
  // stop), from where one or more said "continue" (thread should continue, any "unexpected" votes
  // are ignored).
  bool have_continue = false;

  auto controller_iter = controllers_.begin();
  while (controller_iter != controllers_.end()) {
    ThreadController* controller = controller_iter->get();
    switch (controller->OnThreadStop(info.exception_type, info.hit_breakpoints)) {
      case ThreadController::kContinue:
        // Try the next controller.
        controller->Log("Reported continue on exception.");
        have_continue = true;
        controller_iter++;
        break;
      case ThreadController::kStopDone:
        // Once a controller tells us to stop, we assume the controller no longer applies and delete
        // it.
        //
        // Need to continue with checking all controllers even though we know we should stop at this
        // point. Multiple controllers should say "stop" at the same time and we need to be able to
        // delete all that no longer apply (say you did "finish", hit a breakpoint, and then
        // "finish" again, both finish commands would be active and you would want them both to be
        // completed when the current frame actually finishes).
        controller->Log("Reported stop on exception, stopping and removing it.");
        controller_iter = controllers_.erase(controller_iter);
        should_stop = true;
        break;
      case ThreadController::kUnexpected:
        // An unexpected exception means the controller is still active but doesn't know what to do
        // with this exception.
        controller->Log("Reported unexpected exception.");
        controller_iter++;
        break;
    }
  }

  handling_on_stop_ = false;

  if (!have_continue) {
    // No controller voted to continue (maybe all active controllers reported "unexpected") or there
    // was no controller. Such cases should stop.
    should_stop = true;
  }

  // The existence of any non-internal breakpoints being hit means the thread should always stop.
  // This check happens after notifying the controllers so if a controller triggers, it's counted as
  // a "hit" (otherwise, doing "run until" to a line with a normal breakpoint on it would keep the
  // "run until" operation active even after it was hit).
  //
  // Also, filter out internal breakpoints in the notification sent to the observers.
  StopInfo external_info = info;
  for (size_t i = 0; i < external_info.hit_breakpoints.size(); /* nothing */) {
    if (external_info.hit_breakpoints[i] && !external_info.hit_breakpoints[i]->IsInternal()) {
      should_stop = true;
      i++;
    } else {
      // Erase all deleted weak pointers and internal breakpoints.
      external_info.hit_breakpoints.erase(external_info.hit_breakpoints.begin() + i);
    }
  }

  // Non-debug exceptions also mean the thread should always stop (check this after running the
  // controllers for the same reason as the breakpoint check above).
  if (!debug_ipc::IsDebug(info.exception_type))
    should_stop = true;

  // Execute the chain of post-stop tasks (may be asynchronous) and then dispatch the stop
  // notification or continue operation.
  RunNextPostStopTaskOrNotify(external_info, should_stop);
}

void ThreadImpl::SyncFramesForStack(fit::callback<void(const Err&)> callback) {
  debug_ipc::ThreadStatusRequest request;
  request.id = {.process = process_->GetKoid(), .thread = koid_};

  session()->remote_api()->ThreadStatus(
      request, [callback = std::move(callback), thread = weak_factory_.GetWeakPtr()](
                   const Err& err, debug_ipc::ThreadStatusReply reply) mutable {
        if (err.has_error()) {
          callback(err);
          return;
        }

        if (!thread) {
          callback(Err("Thread destroyed."));
          return;
        }

        thread->SetMetadata(reply.record);
        callback(Err());
      });
}

std::unique_ptr<Frame> ThreadImpl::MakeFrameForStack(const debug_ipc::StackFrame& input,
                                                     Location location) {
  return std::make_unique<FrameImpl>(this, input, std::move(location));
}

Location ThreadImpl::GetSymbolizedLocationForStackFrame(const debug_ipc::StackFrame& input) {
  auto vect = GetProcess()->GetSymbols()->ResolveInputLocation(InputLocation(input.ip));

  // Symbolizing an address should always give exactly one result.
  FX_DCHECK(vect.size() == 1u);
  return vect[0];
}

void ThreadImpl::ClearFrames() {
  if (stack_.ClearFrames()) {
    for (auto& observer : session()->thread_observers())
      observer.OnThreadFramesInvalidated(this);
  }
}

void ThreadImpl::RunNextPostStopTaskOrNotify(const StopInfo& info, bool should_stop) {
  // It's possible that the user is typing "pause" or "continue" during any asynchronous tasks so
  // the thread state doesn't match what we thought it was. Even though we haven't sent the
  // notifications, things still could have happened.
  //
  // Therefore, we don't do anything if the thread has started running from underneath us (it should
  // always be stopped when the thread controllers are notified unless the user has done something),
  // and cancel other pending stop tasks.
  //
  // The other half of the race condition is user has requested a manual stop while we were
  // processing these post-stop tasks and we shouldn't continue it. This needs extra logic to
  // detect.
  //
  // TODO(fxbug.dev/80418) don't automatically continue if the user has stopped the thread.
  if (state_ == debug_ipc::ThreadRecord::State::kRunning) {
    post_stop_tasks_.clear();
    return;
  }

  if (post_stop_tasks_.empty()) {
    // No post-stop tasks left to run, dispatch the stop notification or continue.
    if (should_stop) {
      // Stay stopped and notify the observers.
      for (auto& observer : session()->thread_observers())
        observer.OnThreadStopped(this, info);
    } else {
      // Controllers all say to continue.
      Continue(false);
    }
  } else {
    // Run the next post-stop task.
    PostStopTask task = std::move(post_stop_tasks_.front());
    post_stop_tasks_.pop_front();
    task(fit::defer_callback([weak_this = weak_factory_.GetWeakPtr(), info, should_stop]() mutable {
      if (weak_this)
        weak_this->RunNextPostStopTaskOrNotify(info, should_stop);
    }));
  }
}

}  // namespace zxdb
