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

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

#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/shared/zx_status.h"
#include "src/developer/debug/zxdb/client/client_eval_context_impl.h"
#include "src/developer/debug/zxdb/client/frame_symbol_data_provider.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/thread_impl.h"
#include "src/developer/debug/zxdb/symbols/dwarf_expr_eval.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/input_location.h"
#include "src/developer/debug/zxdb/symbols/symbol.h"
#include "src/developer/debug/zxdb/symbols/variable_location.h"

namespace zxdb {

using debug_ipc::Register;
using debug_ipc::RegisterCategory;

FrameImpl::FrameImpl(Thread* thread, const debug_ipc::StackFrame& stack_frame, Location location)
    : Frame(thread->session()),
      thread_(thread),
      sp_(stack_frame.sp),
      cfa_(stack_frame.cfa),
      location_(std::move(location)),
      weak_factory_(this) {
  registers_[static_cast<size_t>(RegisterCategory::kGeneral)] = stack_frame.regs;
}

FrameImpl::~FrameImpl() {
  if (symbol_data_provider_)
    symbol_data_provider_->Disown();
}

Thread* FrameImpl::GetThread() const { return thread_; }

bool FrameImpl::IsInline() const { return false; }

const Frame* FrameImpl::GetPhysicalFrame() const { return this; }

const Location& FrameImpl::GetLocation() const {
  EnsureSymbolized();
  return location_;
}

uint64_t FrameImpl::GetAddress() const { return location_.address(); }

const std::vector<Register>* FrameImpl::GetRegisterCategorySync(RegisterCategory category) const {
  FX_DCHECK(category <= RegisterCategory::kLast);

  size_t category_index = static_cast<size_t>(category);
  FX_DCHECK(category_index < static_cast<size_t>(RegisterCategory::kLast));

  if (registers_[category_index])
    return &*registers_[category_index];
  return nullptr;
}

void FrameImpl::GetRegisterCategoryAsync(
    RegisterCategory category, bool always_request,
    fit::function<void(const Err&, const std::vector<Register>&)> cb) {
  FX_DCHECK(category < RegisterCategory::kLast && category != RegisterCategory::kNone);

  size_t category_index = static_cast<size_t>(category);
  FX_DCHECK(category_index < static_cast<size_t>(debug_ipc::RegisterCategory::kLast));

  if (!always_request && registers_[category_index]) {
    // Registers known already, asynchronously return the result.
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [cb = std::move(cb), weak_frame = weak_factory_.GetWeakPtr(), category_index]() {
          if (weak_frame)
            cb(Err(), *weak_frame->registers_[category_index]);
          else
            cb(Err("Frame destroyed before registers could be retrieved."), {});
        });
    return;
  }

  // The CPU registers will always refer to the top physical frame so don't fetch them otherwise.
  if (!IsInTopmostPhysicalFrame()) {
    debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE, [cb = std::move(cb)]() {
      cb(Err("This type of register is unavailable in non-topmost stack frames."), {});
    });
    return;
  }

  debug_ipc::ReadRegistersRequest request;
  request.process_koid = thread_->GetProcess()->GetKoid();
  request.thread_koid = thread_->GetKoid();
  request.categories.push_back(category);

  session()->remote_api()->ReadRegisters(
      request, [weak_frame = weak_factory_.GetWeakPtr(), category, cb = std::move(cb)](
                   const Err& err, debug_ipc::ReadRegistersReply reply) mutable {
        if (!weak_frame)
          return cb(Err("Frame destroyed before registers could be retrieved."), {});

        weak_frame->registers_[static_cast<size_t>(category)] = reply.registers;
        cb(Err(), std::move(reply.registers));
      });
  return;
}

void FrameImpl::WriteRegister(debug_ipc::RegisterID id, std::vector<uint8_t> data,
                              fit::callback<void(const Err&)> cb) {
  const debug_ipc::RegisterInfo* info = InfoForRegister(id);
  FX_DCHECK(info);                      // Should always be a valid register.
  FX_DCHECK(info->canonical_id == id);  // Should only write full canonical registers.

  if (!IsInTopmostPhysicalFrame()) {
    debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE, [id, cb = std::move(cb)]() mutable {
      cb(Err("Register %s can't be written when the frame is not the topmost.",
             debug_ipc::RegisterIDToString(id)));
    });
    return;
  }

  debug_ipc::WriteRegistersRequest request;
  request.process_koid = thread_->GetProcess()->GetKoid();
  request.thread_koid = thread_->GetKoid();
  request.registers.emplace_back(id, data);  // Don't move, used below.

  session()->remote_api()->WriteRegisters(
      request, [weak_frame = weak_factory_.GetWeakPtr(), data, cb = std::move(cb)](
                   const Err& err, debug_ipc::WriteRegistersReply reply) mutable {
        if (err.has_error())
          return cb(err);  // Transport error.

        if (reply.status != 0) {
          // Agent error.
          return cb(Err("Error writing register (%s).", debug_ipc::ZxStatusToString(reply.status)));
        }

        if (weak_frame)
          weak_frame->SaveRegisterUpdates(std::move(reply.registers));
        cb(Err());
      });
}

std::optional<uint64_t> FrameImpl::GetBasePointer() const {
  // This function is logically const even though EnsureBasePointer does some potentially mutating
  // things underneath (calling callbacks and such).
  if (const_cast<FrameImpl*>(this)->EnsureBasePointer()) {
    FX_DCHECK(computed_base_pointer_);
    return computed_base_pointer_;
  }
  return std::nullopt;
}

void FrameImpl::GetBasePointerAsync(fit::callback<void(uint64_t bp)> cb) {
  if (EnsureBasePointer()) {
    // BP available synchronously but we don't want to reenter the caller.
    FX_DCHECK(computed_base_pointer_);
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [bp = *computed_base_pointer_, cb = std::move(cb)]() mutable { cb(bp); });
  } else {
    // Add pending request for when evaluation is complete.
    FX_DCHECK(base_pointer_eval_ && !base_pointer_eval_->is_complete());
    base_pointer_requests_.push_back(std::move(cb));
  }
}

uint64_t FrameImpl::GetStackPointer() const { return sp_; }

uint64_t FrameImpl::GetCanonicalFrameAddress() const { return cfa_; }

bool FrameImpl::IsInTopmostPhysicalFrame() const {
  const Stack& stack = GetThread()->GetStack();
  if (stack.empty())
    return false;

  // Search for the first physical frame, and return true if it or anything above it matches the
  // current frame.
  for (size_t i = 0; i < stack.size(); i++) {
    if (stack[i] == this)
      return true;
    if (!stack[i]->IsInline())
      break;
  }
  return false;
}

void FrameImpl::EnsureSymbolized() const {
  if (location_.is_symbolized())
    return;
  auto vect =
      thread_->GetProcess()->GetSymbols()->ResolveInputLocation(InputLocation(location_.address()));
  // Should always return 1 result for symbolizing addresses.
  FX_DCHECK(vect.size() == 1);
  location_ = std::move(vect[0]);
}

fxl::RefPtr<SymbolDataProvider> FrameImpl::GetSymbolDataProvider() const {
  if (!symbol_data_provider_) {
    symbol_data_provider_ =
        fxl::MakeRefCounted<FrameSymbolDataProvider>(const_cast<FrameImpl*>(this));
  }
  return symbol_data_provider_;
}

fxl::RefPtr<EvalContext> FrameImpl::GetEvalContext() const {
  auto language_setting =
      thread_->session()->system().settings().GetString(ClientSettings::System::kLanguage);

  std::optional<ExprLanguage> language = std::nullopt;
  if (language_setting == ClientSettings::System::kLanguage_Rust) {
    language = ExprLanguage::kRust;
  } else if (language_setting == ClientSettings::System::kLanguage_Cpp) {
    language = ExprLanguage::kC;
  } else {
    FX_DCHECK(language_setting == ClientSettings::System::kLanguage_Auto);
  }

  if (!symbol_eval_context_)
    symbol_eval_context_ = fxl::MakeRefCounted<ClientEvalContextImpl>(this, language);
  return symbol_eval_context_;
}

bool FrameImpl::IsAmbiguousInlineLocation() const {
  // This object always represents physical frames which aren't ambiguous.
  return false;
}

bool FrameImpl::EnsureBasePointer() {
  if (computed_base_pointer_)
    return true;  // Already have it available synchronously.

  if (base_pointer_eval_) {
    // Already happening asynchronously.
    FX_DCHECK(!base_pointer_eval_->is_complete());
    return false;
  }

  const Location& loc = GetLocation();
  if (!loc.symbol()) {
    // Unsymbolized.
    computed_base_pointer_ = 0;
    return true;
  }

  const Function* function = loc.symbol().Get()->AsFunction();
  const VariableLocation::Entry* location_entry = nullptr;
  if (!function ||
      !(location_entry = function->frame_base().EntryForIP(loc.symbol_context(), GetAddress()))) {
    // No frame base declared for this function.
    computed_base_pointer_ = 0;
    return true;
  }

  // Try to evaluate the location.
  base_pointer_eval_ = std::make_unique<DwarfExprEval>();

  // Callback when the expression is done. Will normally get called reentrantly by
  // DwarfExpreval::Eval().
  //
  // Binding |this| here is OK because the DwarfExprEval is owned by us and won't give callbacks
  // after it's destroyed.
  auto save_result = [this](DwarfExprEval* eval, const Err&) {
    if (eval->is_success()) {
      computed_base_pointer_ = eval->GetResult();
    } else {
      // We don't currently report errors for frame base requests, but instead just fall back on
      // what was computed by the backend.
      computed_base_pointer_ = 0;
    }

    // Issue callbacks for everybody waiting. Moving to a local here prevents weirdness if a
    // callback calls back into us, and also clears the vector.
    std::vector<fit::callback<void(uint64_t)>> callbacks = std::move(base_pointer_requests_);
    for (auto& cb : callbacks)
      cb(*computed_base_pointer_);
  };

  auto eval_result = base_pointer_eval_->Eval(GetSymbolDataProvider(), loc.symbol_context(),
                                              location_entry->expression, std::move(save_result));

  // In the common case this will complete synchronously and the above callback will have put the
  // result into base_pointer_requests_ before this code is executed.
  return eval_result == DwarfExprEval::Completion::kSync;
}

void FrameImpl::SaveRegisterUpdates(std::vector<Register> regs) {
  std::map<RegisterCategory, std::vector<Register>> categorized;
  for (auto& reg : regs) {
    RegisterCategory cat = RegisterIDToCategory(reg.id);
    FX_DCHECK(cat != RegisterCategory::kNone);
    categorized[cat].push_back(std::move(reg));
  }

  // This function replaces entire categories so we want to clear old registers as we go.
  for (auto& [cat, update] : categorized)
    registers_[static_cast<size_t>(cat)] = std::move(update);
}

}  // namespace zxdb
