//===-- ThreadPlanPython.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/Target/ThreadPlan.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanPython.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"

using namespace lldb;
using namespace lldb_private;

// ThreadPlanPython

ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
                                   StructuredDataImpl *args_data)
    : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
                 eVoteNoOpinion, eVoteNoOpinion),
      m_class_name(class_name), m_args_data(args_data), m_did_push(false),
      m_stop_others(false) {
  SetIsControllingPlan(true);
  SetOkayToDiscard(true);
  SetPrivate(false);
}

ThreadPlanPython::~ThreadPlanPython() {
  // FIXME, do I need to decrement the ref count on this implementation object
  // to make it go away?
}

bool ThreadPlanPython::ValidatePlan(Stream *error) {
  if (!m_did_push)
    return true;

  if (!m_implementation_sp) {
    if (error)
      error->Printf("Error constructing Python ThreadPlan: %s",
          m_error_str.empty() ? "<unknown error>"
                                : m_error_str.c_str());
    return false;
  }

  return true;
}

ScriptInterpreter *ThreadPlanPython::GetScriptInterpreter() {
  return m_process.GetTarget().GetDebugger().GetScriptInterpreter();
}

void ThreadPlanPython::DidPush() {
  // We set up the script side in DidPush, so that it can push other plans in
  // the constructor, and doesn't have to care about the details of DidPush.
  m_did_push = true;
  if (!m_class_name.empty()) {
    ScriptInterpreter *script_interp = GetScriptInterpreter();
    if (script_interp) {
      m_implementation_sp = script_interp->CreateScriptedThreadPlan(
          m_class_name.c_str(), m_args_data, m_error_str, 
          this->shared_from_this());
    }
  }
}

bool ThreadPlanPython::ShouldStop(Event *event_ptr) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());

  bool should_stop = true;
  if (m_implementation_sp) {
    ScriptInterpreter *script_interp = GetScriptInterpreter();
    if (script_interp) {
      bool script_error;
      should_stop = script_interp->ScriptedThreadPlanShouldStop(
          m_implementation_sp, event_ptr, script_error);
      if (script_error)
        SetPlanComplete(false);
    }
  }
  return should_stop;
}

bool ThreadPlanPython::IsPlanStale() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());

  bool is_stale = true;
  if (m_implementation_sp) {
    ScriptInterpreter *script_interp = GetScriptInterpreter();
    if (script_interp) {
      bool script_error;
      is_stale = script_interp->ScriptedThreadPlanIsStale(m_implementation_sp,
                                                          script_error);
      if (script_error)
        SetPlanComplete(false);
    }
  }
  return is_stale;
}

bool ThreadPlanPython::DoPlanExplainsStop(Event *event_ptr) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());

  bool explains_stop = true;
  if (m_implementation_sp) {
    ScriptInterpreter *script_interp = GetScriptInterpreter();
    if (script_interp) {
      bool script_error;
      explains_stop = script_interp->ScriptedThreadPlanExplainsStop(
          m_implementation_sp, event_ptr, script_error);
      if (script_error)
        SetPlanComplete(false);
    }
  }
  return explains_stop;
}

bool ThreadPlanPython::MischiefManaged() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());
  bool mischief_managed = true;
  if (m_implementation_sp) {
    // I don't really need mischief_managed, since it's simpler to just call
    // SetPlanComplete in should_stop.
    mischief_managed = IsPlanComplete();
    if (mischief_managed)
      m_implementation_sp.reset();
  }
  return mischief_managed;
}

lldb::StateType ThreadPlanPython::GetPlanRunState() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());
  lldb::StateType run_state = eStateRunning;
  if (m_implementation_sp) {
    ScriptInterpreter *script_interp = GetScriptInterpreter();
    if (script_interp) {
      bool script_error;
      run_state = script_interp->ScriptedThreadPlanGetRunState(
          m_implementation_sp, script_error);
    }
  }
  return run_state;
}

// The ones below are not currently exported to Python.
void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
  s->Printf("Python thread plan implemented by class %s.",
            m_class_name.c_str());
}

bool ThreadPlanPython::WillStop() {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
  LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION,
            m_class_name.c_str());
  return true;
}
