//===-- Policy.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/Utility/Policy.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/Support/ErrorHandling.h"

using namespace lldb_private;

// Declared out-of-line so every shared library resolves to the same
// instance: a function-local static in an inline function is not
// shared across shared library boundaries under hidden visibility.
PolicyStack &PolicyStack::Get() {
  static thread_local PolicyStack s_stack;
  return s_stack;
}

Policy PolicyStack::Current() const {
  Policy p = m_stack.back();
  // `Current()` is called on every read of the current policy (e.g. every
  // `Process::GetState()`, itself called on every prompt redraw), so log
  // only when verbose is set to avoid drowning out the process log.
  if (Log *log = GetLog(LLDBLog::Process)) {
    if (log->GetVerbose()) {
      StreamString s;
      p.Dump(s);
      LLDB_LOG(log, "{0}", s.GetData());
    }
  }
  return p;
}

// CreatePublicState is the baseline, not a transition. The stack returns to
// public state by popping the private-state guards, not by pushing a
// "public" policy on top. This factory exists only as a reference value
// (tests, dump comparisons); it never reads the current stack.
Policy Policy::CreatePublicState() { return {}; }

Policy Policy::CreatePrivateState(PrivateStatePurpose purpose) {
  Policy p = PolicyStack::Get().Current();
  p.view = View::Private;
  switch (purpose) {
  case PrivateStatePurpose::Default:
    break;
  case PrivateStatePurpose::RunningExpression:
    p.capabilities.can_load_frame_providers = false;
    p.capabilities.can_run_frame_recognizers = false;
    break;
  }
  return p;
}

Policy Policy::CreatePublicStateRunningExpression() {
  Policy p = PolicyStack::Get().Current();
  p.capabilities.can_run_breakpoint_actions = false;
  return p;
}

// A scripted extension invoked by the debugger must not perturb the state it
// was asked to describe, so an expression started from one stays on its own
// thread. This scope is not pushed for scripted commands, which the user
// invokes directly.
Policy Policy::CreateScriptedExtensionCall() {
  Policy p = PolicyStack::Get().Current();
  p.capabilities.can_bypass_target_api_mutex = true;
  p.capabilities.can_run_all_threads = false;
  p.capabilities.can_try_all_threads = false;
  return p;
}

PolicyStack::Guard::~Guard() {
  if (!m_active)
    return;
  if (m_thread_id != std::this_thread::get_id())
    llvm::report_fatal_error(
        "PolicyStack::Guard destroyed on a different thread than the one "
        "that created it");
  Get().Pop();
}

PolicyStack::Guard::Guard(Guard &&other)
    : m_thread_id(other.m_thread_id), m_active(other.m_active) {
  if (m_active && m_thread_id != std::this_thread::get_id())
    llvm::report_fatal_error("PolicyStack::Guard moved across threads");
  other.m_active = false;
}

PolicyStack::Guard &PolicyStack::Guard::operator=(Guard &&other) {
  if (this != &other) {
    if (other.m_active && other.m_thread_id != std::this_thread::get_id())
      llvm::report_fatal_error("PolicyStack::Guard moved across threads");
    if (m_active) {
      if (m_thread_id != std::this_thread::get_id())
        llvm::report_fatal_error(
            "PolicyStack::Guard destroyed on a different thread than the "
            "one that created it");
      Get().Pop();
    }
    m_thread_id = other.m_thread_id;
    m_active = other.m_active;
    other.m_active = false;
  }
  return *this;
}

void Policy::Dump(Stream &s) const {
  s << "policy: view=" << (view == View::Public ? "public" : "private");
  s << ", capabilities={";
  s << "eval_expr=" << capabilities.can_evaluate_expressions;
  s << " run_all=" << capabilities.can_run_all_threads;
  s << " try_all=" << capabilities.can_try_all_threads;
  s << " bp_actions=" << capabilities.can_run_breakpoint_actions;
  s << " frame_providers=" << capabilities.can_load_frame_providers;
  s << " frame_recognizers=" << capabilities.can_run_frame_recognizers;
  s << " bypass_api_mutex=" << capabilities.can_bypass_target_api_mutex;
  s << '}';
}

void PolicyStack::Dump(Stream &s) const {
  s.Printf("PolicyStack depth=%zu\n", m_stack.size());
  for (size_t i = 0; i < m_stack.size(); i++) {
    s.Printf("  [%zu] ", i);
    m_stack[i].Dump(s);
    s << '\n';
  }
}
