//===-- WatchpointOptions.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Breakpoint/WatchpointOptions.h"

#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"

using namespace lldb;
using namespace lldb_private;

bool WatchpointOptions::NullCallback(void *baton,
                                     StoppointCallbackContext *context,
                                     lldb::user_id_t watch_id) {
  return true;
}

// WatchpointOptions constructor
WatchpointOptions::WatchpointOptions()
    : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(),
      m_callback_is_synchronous(false), m_thread_spec_up() {}

// WatchpointOptions copy constructor
WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
    : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
      m_callback_is_synchronous(rhs.m_callback_is_synchronous),
      m_thread_spec_up() {
  if (rhs.m_thread_spec_up != nullptr)
    m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
}

// WatchpointOptions assignment operator
const WatchpointOptions &WatchpointOptions::
operator=(const WatchpointOptions &rhs) {
  m_callback = rhs.m_callback;
  m_callback_baton_sp = rhs.m_callback_baton_sp;
  m_callback_is_synchronous = rhs.m_callback_is_synchronous;
  if (rhs.m_thread_spec_up != nullptr)
    m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
  return *this;
}

WatchpointOptions *
WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
  WatchpointHitCallback orig_callback = orig.m_callback;
  lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
  bool orig_is_sync = orig.m_callback_is_synchronous;

  orig.ClearCallback();
  WatchpointOptions *ret_val = new WatchpointOptions(orig);

  orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);

  return ret_val;
}

// Destructor
WatchpointOptions::~WatchpointOptions() = default;

// Callbacks
void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
                                    const BatonSP &callback_baton_sp,
                                    bool callback_is_synchronous) {
  m_callback_is_synchronous = callback_is_synchronous;
  m_callback = callback;
  m_callback_baton_sp = callback_baton_sp;
}

void WatchpointOptions::ClearCallback() {
  m_callback = WatchpointOptions::NullCallback;
  m_callback_is_synchronous = false;
  m_callback_baton_sp.reset();
}

Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }

const Baton *WatchpointOptions::GetBaton() const {
  return m_callback_baton_sp.get();
}

bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
                                       lldb::user_id_t watch_id) {
  if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
    return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
                                          : nullptr,
                      context, watch_id);
  } else
    return true;
}

bool WatchpointOptions::HasCallback() {
  return m_callback != WatchpointOptions::NullCallback;
}

const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
  return m_thread_spec_up.get();
}

ThreadSpec *WatchpointOptions::GetThreadSpec() {
  if (m_thread_spec_up == nullptr)
    m_thread_spec_up = std::make_unique<ThreadSpec>();

  return m_thread_spec_up.get();
}

void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
  GetThreadSpec()->SetTID(thread_id);
}

void WatchpointOptions::GetCallbackDescription(
    Stream *s, lldb::DescriptionLevel level) const {
  if (m_callback_baton_sp.get()) {
    s->EOL();
    m_callback_baton_sp->GetDescription(s->AsRawOstream(), level,
                                        s->GetIndentLevel());
  }
}

void WatchpointOptions::GetDescription(Stream *s,
                                       lldb::DescriptionLevel level) const {
  // Figure out if there are any options not at their default value, and only
  // print anything if there are:

  if ((GetThreadSpecNoCreate() != nullptr &&
       GetThreadSpecNoCreate()->HasSpecification())) {
    if (level == lldb::eDescriptionLevelVerbose) {
      s->EOL();
      s->IndentMore();
      s->Indent();
      s->PutCString("Watchpoint Options:\n");
      s->IndentMore();
      s->Indent();
    } else
      s->PutCString(" Options: ");

    if (m_thread_spec_up)
      m_thread_spec_up->GetDescription(s, level);
    else if (level == eDescriptionLevelBrief)
      s->PutCString("thread spec: no ");
    if (level == lldb::eDescriptionLevelFull) {
      s->IndentLess();
      s->IndentMore();
    }
  }

  GetCallbackDescription(s, level);
}

void WatchpointOptions::CommandBaton::GetDescription(
    llvm::raw_ostream &s, lldb::DescriptionLevel level,
    unsigned indentation) const {
  const CommandData *data = getItem();

  if (level == eDescriptionLevelBrief) {
    s << ", commands = %s"
      << ((data && data->user_source.GetSize() > 0) ? "yes" : "no");
    return;
  }

  indentation += 2;
  s.indent(indentation);
  s << "watchpoint commands:\n";

  indentation += 2;
  if (data && data->user_source.GetSize() > 0) {
    for (const std::string &line : data->user_source) {
      s.indent(indentation);
      s << line << "\n";
    }
  } else
    s << "No commands.\n";
}
