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

#include <stdarg.h>

#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/symbols/function.h"

namespace zxdb {

ThreadController::ThreadController() = default;

ThreadController::~ThreadController() = default;

#if defined(DEBUG_THREAD_CONTROLLERS)
void ThreadController::Log(const char* format, ...) const {
  va_list ap;
  va_start(ap, format);

  printf("%s controller: ", GetName());
  vprintf(format, ap);

  // Manually add \r so output will be reasonable even if the terminal is in
  // raw mode.
  printf("\r\n");

  va_end(ap);
}

// static
void ThreadController::LogRaw(const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  vprintf(format, ap);
  printf("\r\n");
  va_end(ap);
}

// static
std::string ThreadController::FrameFunctionNameForLog(const Frame* frame) {
  const char kNone[] = "<none>";

  const Location& loc = frame->GetLocation();
  if (!loc.symbol())
    return kNone;

  const Function* func = loc.symbol().Get()->AsFunction();
  if (!func)
    return kNone;

  return func->GetFullName();
}
#endif

void ThreadController::SetInlineFrameIfAmbiguous(InlineFrameIs comparison,
                                                 FrameFingerprint fingerprint) {
  Stack& stack = thread()->GetStack();

  // Reset any hidden inline frames so we can iterate through all of them
  // (and we'll leave this reset to 0 if the requested one isn't found).
  size_t old_hide_count = stack.hide_ambiguous_inline_frame_count();
  stack.SetHideAmbiguousInlineFrameCount(0);

  for (size_t i = 0; i < stack.size(); i++) {
    const Frame* frame = stack[i];
    auto found = stack.GetFrameFingerprint(i);
    if (!found)
      break;  // Got to bottom of computable fingerprints, give up.

    // To be ambiguous, all frames to here need to be at the same address and
    // all inline frames need to be at the beginning of one of their ranges.
    // (the physical frame also needs matching but its range doesn't count).
    bool is_inline = frame->IsInline();

    if (*found == fingerprint) {
      // Found it.
      if (comparison == InlineFrameIs::kEqual) {
        // Make this one the top of the stack.
        stack.SetHideAmbiguousInlineFrameCount(i);
        return;
      } else {  // comparison == InlineFrameIs::kOneBefore.
        // Make the one below this frame topmost. That requires the current
        // frame be inline since it will be hidden.
        if (is_inline) {
          stack.SetHideAmbiguousInlineFrameCount(i + 1);
          return;
        }
      }
      break;
    }

    if (!is_inline)
      break;  // Don't check below the first physical frame.

    // The fingerprint can be set on a frame as long as all frames above it
    // were ambiguous, but the frame being set to is usually not ambiguous
    // (it's often the physical frame that calls an inline function, for
    // example).
    if (!frame->IsAmbiguousInlineLocation())
      break;
  }

  if (old_hide_count)
    stack.SetHideAmbiguousInlineFrameCount(old_hide_count);
}

void ThreadController::NotifyControllerDone() {
  thread_->NotifyControllerDone(this);
  // Warning: |this| is likely deleted.
}

}  // namespace zxdb
