//===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H

#include "lldb-python.h"

#include "PythonDataObjects.h"
#include "ScriptInterpreterPython.h"

#include "lldb/Host/Terminal.h"
#include "lldb/Utility/StreamString.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"

namespace lldb_private {
class IOHandlerPythonInterpreter;
class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
public:
  friend class IOHandlerPythonInterpreter;

  ScriptInterpreterPythonImpl(Debugger &debugger);

  ~ScriptInterpreterPythonImpl() override;

  bool Interrupt() override;

  bool ExecuteOneLine(
      llvm::StringRef command, CommandReturnObject *result,
      const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;

  void ExecuteInterpreterLoop() override;

  bool ExecuteOneLineWithReturn(
      llvm::StringRef in_string,
      ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
      const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;

  lldb_private::Status ExecuteMultipleLines(
      const char *in_string,
      const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;

  Status
  ExportFunctionDefinitionToInterpreter(StringList &function_def) override;

  bool GenerateTypeScriptFunction(StringList &input, std::string &output,
                                  const void *name_token = nullptr) override;

  bool GenerateTypeSynthClass(StringList &input, std::string &output,
                              const void *name_token = nullptr) override;

  bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
                              const void *name_token = nullptr) override;

  // use this if the function code is just a one-liner script
  bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
                                  const void *name_token = nullptr) override;

  bool GenerateScriptAliasFunction(StringList &input,
                                   std::string &output) override;

  StructuredData::ObjectSP
  CreateSyntheticScriptedProvider(const char *class_name,
                                  lldb::ValueObjectSP valobj) override;

  StructuredData::GenericSP
  CreateScriptCommandObject(const char *class_name) override;

  StructuredData::ObjectSP
  CreateStructuredDataFromScriptObject(ScriptObject obj) override;

  lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override;

  lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override;

  lldb::ScriptedBreakpointInterfaceSP
  CreateScriptedBreakpointInterface() override;

  lldb::ScriptedStackFrameRecognizerInterfaceSP
  CreateScriptedStackFrameRecognizerInterface() override;

  lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;

  lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override;

  lldb::ScriptedFrameProviderInterfaceSP
  CreateScriptedFrameProviderInterface() override;

  lldb::ScriptedThreadPlanInterfaceSP
  CreateScriptedThreadPlanInterface() override;

  lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;

  StructuredData::ObjectSP
  LoadPluginModule(const FileSpec &file_spec,
                   lldb_private::Status &error) override;

  StructuredData::DictionarySP
  GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
                     const char *setting_name,
                     lldb_private::Status &error) override;

  size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
                              uint32_t max) override;

  lldb::ValueObjectSP
  GetChildAtIndex(const StructuredData::ObjectSP &implementor,
                  uint32_t idx) override;

  llvm::Expected<uint32_t>
  GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
                          const char *child_name) override;

  bool UpdateSynthProviderInstance(
      const StructuredData::ObjectSP &implementor) override;

  bool MightHaveChildrenSynthProviderInstance(
      const StructuredData::ObjectSP &implementor) override;

  lldb::ValueObjectSP
  GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;

  ConstString
  GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;

  bool
  RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
                        ScriptedCommandSynchronicity synchronicity,
                        lldb_private::CommandReturnObject &cmd_retobj,
                        Status &error,
                        const lldb_private::ExecutionContext &exe_ctx) override;

  bool RunScriptBasedCommand(
      StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
      ScriptedCommandSynchronicity synchronicity,
      lldb_private::CommandReturnObject &cmd_retobj, Status &error,
      const lldb_private::ExecutionContext &exe_ctx) override;

  bool RunScriptBasedParsedCommand(
      StructuredData::GenericSP impl_obj_sp, Args &args,
      ScriptedCommandSynchronicity synchronicity,
      lldb_private::CommandReturnObject &cmd_retobj, Status &error,
      const lldb_private::ExecutionContext &exe_ctx) override;

  std::optional<std::string>
  GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp,
                                     Args &args) override;

  StructuredData::DictionarySP HandleArgumentCompletionForScriptedCommand(
      StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args,
      size_t args_pos, size_t char_in_arg) override;

  StructuredData::DictionarySP HandleOptionArgumentCompletionForScriptedCommand(
      StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_options,
      size_t char_in_arg) override;

  Status GenerateFunction(const char *signature, const StringList &input,
                          bool is_callback) override;

  Status GenerateBreakpointCommandCallbackData(StringList &input,
                                               std::string &output,
                                               bool has_extra_args,
                                               bool is_callback) override;

  bool GenerateWatchpointCommandCallbackData(StringList &input,
                                             std::string &output,
                                             bool is_callback) override;

  bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
                          StructuredData::ObjectSP &callee_wrapper_sp,
                          const TypeSummaryOptions &options,
                          std::string &retval) override;

  bool FormatterCallbackFunction(const char *function_name,
                                 lldb::TypeImplSP type_impl_sp) override;

  bool GetDocumentationForItem(const char *item, std::string &dest) override;

  bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
                                    std::string &dest) override;

  uint32_t
  GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;

  bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
                                   std::string &dest) override;

  StructuredData::ObjectSP
  GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;

  StructuredData::ObjectSP
  GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override;

  bool SetOptionValueForCommandObject(StructuredData::GenericSP cmd_obj_sp,
                                      ExecutionContext *exe_ctx,
                                      llvm::StringRef long_option,
                                      llvm::StringRef value) override;

  void OptionParsingStartedForCommandObject(
      StructuredData::GenericSP cmd_obj_sp) override;

  bool CheckObjectExists(const char *name) override {
    if (!name || !name[0])
      return false;
    std::string temp;
    return GetDocumentationForItem(name, temp);
  }

  bool RunScriptFormatKeyword(const char *impl_function, Process *process,
                              std::string &output, Status &error) override;

  bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
                              std::string &output, Status &error) override;

  bool RunScriptFormatKeyword(const char *impl_function, Target *target,
                              std::string &output, Status &error) override;

  bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
                              std::string &output, Status &error) override;

  bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
                              std::string &output, Status &error) override;

  bool LoadScriptingModule(const char *filename,
                           const LoadScriptOptions &options,
                           lldb_private::Status &error,
                           StructuredData::ObjectSP *module_sp = nullptr,
                           FileSpec extra_search_dir = {},
                           lldb::TargetSP loaded_into_target_sp = {}) override;

  bool IsReservedWord(const char *word) override;

  std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;

  void CollectDataForBreakpointCommandCallback(
      std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
      CommandReturnObject &result) override;

  void
  CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
                                          CommandReturnObject &result) override;

  /// Set the callback body text into the callback for the breakpoint.
  Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
                                      const char *callback_body,
                                      bool is_callback) override;

  Status SetBreakpointCommandCallbackFunction(
      BreakpointOptions &bp_options, const char *function_name,
      StructuredData::ObjectSP extra_args_sp) override;

  /// This one is for deserialization:
  Status SetBreakpointCommandCallback(
      BreakpointOptions &bp_options,
      std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;

  Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
                                      const char *command_body_text,
                                      StructuredData::ObjectSP extra_args_sp,
                                      bool uses_extra_args, bool is_callback);

  /// Set a one-liner as the callback for the watchpoint.
  void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
                                    const char *user_input,
                                    bool is_callback) override;

  const char *GetDictionaryName() { return m_dictionary_name.c_str(); }

  PyThreadState *GetThreadState() { return m_command_thread_state; }

  void SetThreadState(PyThreadState *s) {
    if (s)
      m_command_thread_state = s;
  }

  // IOHandlerDelegate
  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;

  void IOHandlerInputComplete(IOHandler &io_handler,
                              std::string &data) override;

  static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger);

  // PluginInterface protocol
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

  class Locker : public ScriptInterpreterLocker {
  public:
    enum OnEntry {
      AcquireLock = 0x0001,
      InitSession = 0x0002,
      InitGlobals = 0x0004,
      NoSTDIN = 0x0008,
      // Keep sys.stdout/stderr on the real terminal instead of routing them
      // through the output-lock pipe (see EnterSession). Set by the interactive
      // interpreter, whose input() needs both the real stdin and stdout for
      // readline-based line editing and echo.
      NoOutputRedirect = 0x0010
    };

    enum OnLeave {
      FreeLock = 0x0001,
      FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
                                 // when calling constructor
      TearDownSession = 0x0004
    };

    Locker(ScriptInterpreterPythonImpl *py_interpreter,
           uint16_t on_entry = AcquireLock | InitSession,
           uint16_t on_leave = FreeLock | TearDownSession,
           lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
           lldb::FileSP err = nullptr);

    ~Locker() override;

  private:
    bool DoAcquireLock();

    bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
                       lldb::FileSP out, lldb::FileSP err);

    bool DoFreeLock();

    bool DoTearDownSession();

    bool m_teardown_session;
    ScriptInterpreterPythonImpl *m_python_interpreter;
    PyGILState_STATE m_GILState;
  };

  static bool BreakpointCallbackFunction(void *baton,
                                         StoppointCallbackContext *context,
                                         lldb::user_id_t break_id,
                                         lldb::user_id_t break_loc_id);
  static bool WatchpointCallbackFunction(void *baton,
                                         StoppointCallbackContext *context,
                                         lldb::user_id_t watch_id);
  static void Initialize();

  class SynchronicityHandler {
  private:
    lldb::DebuggerSP m_debugger_sp;
    ScriptedCommandSynchronicity m_synch_wanted;
    bool m_old_asynch;

  public:
    SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity);

    ~SynchronicityHandler();
  };

  enum class AddLocation { Beginning, End };

  static void AddToSysPath(AddLocation location, std::string path);

  bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
                    lldb::FileSP err);

  void LeaveSession();

  uint32_t IsExecutingPython() {
    std::lock_guard<std::mutex> guard(m_mutex);
    return m_lock_count > 0;
  }

  uint32_t IncrementLockCount() {
    std::lock_guard<std::mutex> guard(m_mutex);
    return ++m_lock_count;
  }

  uint32_t DecrementLockCount() {
    std::lock_guard<std::mutex> guard(m_mutex);
    if (m_lock_count > 0)
      --m_lock_count;
    return m_lock_count;
  }

  enum ActiveIOHandler {
    eIOHandlerNone,
    eIOHandlerBreakpoint,
    eIOHandlerWatchpoint
  };

  python::PythonModule &GetMainModule();

  python::PythonDictionary &GetSessionDictionary();

  python::PythonDictionary &GetSysModuleDictionary();

  llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable(
      const llvm::StringRef &callable_name) override;

  bool GetEmbeddedInterpreterModuleObjects();

  /// Point sys.\p py_name at \p file. When \p serialize_terminal_output is true
  /// and \p file is the debugger's own terminal, the output is routed through a
  /// lock-synchronized pipe instead (see RedirectTerminalHandleThroughLock) so
  /// it cannot race the statusline redraw.
  bool SetStdHandle(lldb::FileSP file, const char *py_name,
                    python::PythonObject &save_file, const char *mode,
                    bool serialize_terminal_output);

  /// Pipe-backed sys.stdout/stderr whose writes are serialized against the
  /// statusline redraw. Defined and documented in the implementation file.
  class SessionIORedirect;

  /// If \p file is the debugger's own terminal, point sys.\p py_name at a
  /// pipe-backed file whose writes are serialized through the output lock (see
  /// SessionIORedirect) and return true. Return false to let SetStdHandle wrap
  /// \p file normally.
  bool RedirectTerminalHandleThroughLock(const char *py_name,
                                         python::PythonObject &save_file,
                                         const char *mode, File &file);

  python::PythonObject m_saved_stdin;
  python::PythonObject m_saved_stdout;
  python::PythonObject m_saved_stderr;
  std::unique_ptr<SessionIORedirect> m_stdout_redirect;
  std::unique_ptr<SessionIORedirect> m_stderr_redirect;
  python::PythonModule m_main_module;
  python::PythonDictionary m_session_dict;
  python::PythonDictionary m_sys_module_dict;
  python::PythonObject m_run_one_line_function;
  python::PythonObject m_run_one_line_str_global;
  std::string m_dictionary_name;
  ActiveIOHandler m_active_io_handler;
  bool m_session_is_active;
  bool m_pty_secondary_is_open;
  bool m_valid_session;
  uint32_t m_lock_count;
  std::mutex m_mutex;
  PyThreadState *m_command_thread_state;
};

class IOHandlerPythonInterpreter : public IOHandler {
public:
  IOHandlerPythonInterpreter(Debugger &debugger,
                             ScriptInterpreterPythonImpl *python)
      : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
        m_python(python) {}

  ~IOHandlerPythonInterpreter() override = default;

  llvm::StringRef GetControlSequence(char ch) override {
    static constexpr llvm::StringLiteral control_sequence("quit()\n");
    if (ch == 'd')
      return control_sequence;
    return {};
  }

  void Run() override {
    if (m_python) {
      int stdin_fd = GetInputFD();
      if (stdin_fd >= 0) {
        Terminal terminal(stdin_fd);
        TerminalState terminal_state(terminal);

        if (terminal.IsATerminal()) {
          // FIXME: error handling?
          llvm::consumeError(terminal.SetCanonical(false));
          llvm::consumeError(terminal.SetEcho(true));
        }

        ScriptInterpreterPythonImpl::Locker locker(
            m_python,
            ScriptInterpreterPythonImpl::Locker::AcquireLock |
                ScriptInterpreterPythonImpl::Locker::InitSession |
                ScriptInterpreterPythonImpl::Locker::InitGlobals |
                ScriptInterpreterPythonImpl::Locker::NoOutputRedirect,
            ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock |
                ScriptInterpreterPythonImpl::Locker::TearDownSession);

        // The following call drops into the embedded interpreter loop and
        // stays there until the user chooses to exit from the Python
        // interpreter. This embedded interpreter will, as any Python code that
        // performs I/O, unlock the GIL before a system call that can hang, and
        // lock it when the syscall has returned.

        // We need to surround the call to the embedded interpreter with calls
        // to PyGILState_Ensure and PyGILState_Release (using the Locker
        // above). This is because Python has a global lock which must be held
        // whenever we want to touch any Python objects. Otherwise, if the user
        // calls Python code, the interpreter state will be off, and things
        // could hang (it's happened before).

        StreamString run_string;
        run_string.Printf("run_python_interpreter (%s)",
                          m_python->GetDictionaryName());
        python::RunSimpleString(run_string.GetData());
      }
    }
    SetIsDone(true);
  }

  void Cancel() override {}

  bool Interrupt() override { return m_python->Interrupt(); }

  void GotEOF() override {}

protected:
  ScriptInterpreterPythonImpl *m_python;
};

} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
