//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H

#ifdef LLDB_DISABLE_PYTHON

// Python is disabled in this build

#else

// C Includes
// C++ Includes
#include <memory>
#include <string>
#include <vector>

// Other libraries and framework includes
// Project includes
#include "PythonDataObjects.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/lldb-private.h"

class IOHandlerPythonInterpreter;

namespace lldb_private {

class ScriptInterpreterPython : public ScriptInterpreter,
                                public IOHandlerDelegateMultiline {
public:
  class CommandDataPython : public BreakpointOptions::CommandData {
  public:
    CommandDataPython() : BreakpointOptions::CommandData() {
      interpreter = lldb::eScriptLanguagePython;
    }
  };

#if PY_MAJOR_VERSION >= 3
  typedef PyObject *(*SWIGInitCallback)(void);
#else
  typedef void (*SWIGInitCallback)(void);
#endif

  typedef bool (*SWIGBreakpointCallbackFunction)(
      const char *python_function_name, const char *session_dictionary_name,
      const lldb::StackFrameSP &frame_sp,
      const lldb::BreakpointLocationSP &bp_loc_sp);

  typedef bool (*SWIGWatchpointCallbackFunction)(
      const char *python_function_name, const char *session_dictionary_name,
      const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp);

  typedef bool (*SWIGPythonTypeScriptCallbackFunction)(
      const char *python_function_name, void *session_dictionary,
      const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
      const lldb::TypeSummaryOptionsSP &options, std::string &retval);

  typedef void *(*SWIGPythonCreateSyntheticProvider)(
      const char *python_class_name, const char *session_dictionary_name,
      const lldb::ValueObjectSP &valobj_sp);

  typedef void *(*SWIGPythonCreateCommandObject)(
      const char *python_class_name, const char *session_dictionary_name,
      const lldb::DebuggerSP debugger_sp);

  typedef void *(*SWIGPythonCreateScriptedThreadPlan)(
      const char *python_class_name, const char *session_dictionary_name,
      const lldb::ThreadPlanSP &thread_plan_sp);

  typedef bool (*SWIGPythonCallThreadPlan)(void *implementor,
                                           const char *method_name,
                                           Event *event_sp, bool &got_error);

  typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name,
                                            const char *session_dictionary_name,
                                            const lldb::ProcessSP &process_sp);

  typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor,
                                                   uint32_t max);

  typedef void *(*SWIGPythonGetChildAtIndex)(void *implementor, uint32_t idx);

  typedef int (*SWIGPythonGetIndexOfChildWithName)(void *implementor,
                                                   const char *child_name);

  typedef void *(*SWIGPythonCastPyObjectToSBValue)(void *data);

  typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue)(
      void *data);

  typedef bool (*SWIGPythonUpdateSynthProviderInstance)(void *data);

  typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance)(void *data);

  typedef void *(*SWIGPythonGetValueSynthProviderInstance)(void *implementor);

  typedef bool (*SWIGPythonCallCommand)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::DebuggerSP &debugger, const char *args,
      lldb_private::CommandReturnObject &cmd_retobj,
      lldb::ExecutionContextRefSP exe_ctx_ref_sp);

  typedef bool (*SWIGPythonCallCommandObject)(
      void *implementor, lldb::DebuggerSP &debugger, const char *args,
      lldb_private::CommandReturnObject &cmd_retobj,
      lldb::ExecutionContextRefSP exe_ctx_ref_sp);

  typedef bool (*SWIGPythonCallModuleInit)(const char *python_module_name,
                                           const char *session_dictionary_name,
                                           lldb::DebuggerSP &debugger);

  typedef bool (*SWIGPythonScriptKeyword_Process)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::ProcessSP &process, std::string &output);

  typedef bool (*SWIGPythonScriptKeyword_Thread)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::ThreadSP &thread, std::string &output);

  typedef bool (*SWIGPythonScriptKeyword_Target)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::TargetSP &target, std::string &output);

  typedef bool (*SWIGPythonScriptKeyword_Frame)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::StackFrameSP &frame, std::string &output);

  typedef bool (*SWIGPythonScriptKeyword_Value)(
      const char *python_function_name, const char *session_dictionary_name,
      lldb::ValueObjectSP &value, std::string &output);

  typedef void *(*SWIGPython_GetDynamicSetting)(
      void *module, const char *setting, const lldb::TargetSP &target_sp);

  friend class ::IOHandlerPythonInterpreter;

  ScriptInterpreterPython(CommandInterpreter &interpreter);

  ~ScriptInterpreterPython() override;

  bool Interrupt() override;

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

  void ExecuteInterpreterLoop() override;

  bool ExecuteOneLineWithReturn(
      const char *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
  CreateScriptedThreadPlan(const char *class_name,
                           lldb::ThreadPlanSP thread_plan) override;

  bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
                                      Event *event,
                                      bool &script_error) override;

  bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
                                    Event *event, bool &script_error) override;

  bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
                                 bool &script_error) override;

  lldb::StateType
  ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
                                bool &script_error) override;

  StructuredData::GenericSP
  OSPlugin_CreatePluginObject(const char *class_name,
                              lldb::ProcessSP process_sp) override;

  StructuredData::DictionarySP
  OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;

  StructuredData::ArraySP
  OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;

  StructuredData::StringSP
  OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
                               lldb::tid_t thread_id) override;

  StructuredData::DictionarySP
  OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
                        lldb::tid_t tid, lldb::addr_t context) 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;

  int 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, const char *args,
                        ScriptedCommandSynchronicity synchronicity,
                        lldb_private::CommandReturnObject &cmd_retobj,
                        Status &error,
                        const lldb_private::ExecutionContext &exe_ctx) override;

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

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

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

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

  //    static size_t
  //    GenerateBreakpointOptionsCommandCallback (void *baton,
  //                                              InputReader &reader,
  //                                              lldb::InputReaderAction
  //                                              notification,
  //                                              const char *bytes,
  //                                              size_t bytes_len);
  //
  //    static size_t
  //    GenerateWatchpointOptionsCommandCallback (void *baton,
  //                                              InputReader &reader,
  //                                              lldb::InputReaderAction
  //                                              notification,
  //                                              const char *bytes,
  //                                              size_t bytes_len);

  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);

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

  void Clear() 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;

  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, bool can_reload, bool init_session,
                      lldb_private::Status &error,
                      StructuredData::ObjectSP *module_sp = nullptr) override;

  bool IsReservedWord(const char *word) override;

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

  void CollectDataForBreakpointCommandCallback(
      std::vector<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) override;

  void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options,
                                            const char *function_name) override;

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

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

  StringList ReadCommandInputFromUser(FILE *in_file);

  void ResetOutputFileHandle(FILE *new_fh) override;

  static void InitializePrivate();

  static void InitializeInterpreter(
      SWIGInitCallback python_swig_init_callback,
      SWIGBreakpointCallbackFunction swig_breakpoint_callback,
      SWIGWatchpointCallbackFunction swig_watchpoint_callback,
      SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
      SWIGPythonCreateSyntheticProvider swig_synthetic_script,
      SWIGPythonCreateCommandObject swig_create_cmd,
      SWIGPythonCalculateNumChildren swig_calc_children,
      SWIGPythonGetChildAtIndex swig_get_child_index,
      SWIGPythonGetIndexOfChildWithName swig_get_index_child,
      SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue,
      SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
      SWIGPythonUpdateSynthProviderInstance swig_update_provider,
      SWIGPythonMightHaveChildrenSynthProviderInstance
          swig_mighthavechildren_provider,
      SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider,
      SWIGPythonCallCommand swig_call_command,
      SWIGPythonCallCommandObject swig_call_command_object,
      SWIGPythonCallModuleInit swig_call_module_init,
      SWIGPythonCreateOSPlugin swig_create_os_plugin,
      SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
      SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
      SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
      SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
      SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
      SWIGPython_GetDynamicSetting swig_plugin_get,
      SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
      SWIGPythonCallThreadPlan swig_call_thread_plan);

  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) override;

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

  //------------------------------------------------------------------
  // Static Functions
  //------------------------------------------------------------------
  static void Initialize();

  static void Terminate();

  static lldb::ScriptInterpreterSP
  CreateInstance(CommandInterpreter &interpreter);

  static lldb_private::ConstString GetPluginNameStatic();

  static const char *GetPluginDescriptionStatic();

  //------------------------------------------------------------------
  // PluginInterface protocol
  //------------------------------------------------------------------
  lldb_private::ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

  class Locker : public ScriptInterpreterLocker {
  public:
    enum OnEntry {
      AcquireLock = 0x0001,
      InitSession = 0x0002,
      InitGlobals = 0x0004,
      NoSTDIN = 0x0008
    };

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

    Locker(ScriptInterpreterPython *py_interpreter = nullptr,
           uint16_t on_entry = AcquireLock | InitSession,
           uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr,
           FILE *out = nullptr, FILE *err = nullptr);

    ~Locker() override;

  private:
    bool DoAcquireLock();

    bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err);

    bool DoFreeLock();

    bool DoTearDownSession();

    static void ReleasePythonLock();

    bool m_teardown_session;
    ScriptInterpreterPython *m_python_interpreter;
    //    	FILE*                    m_tmp_fh;
    PyGILState_STATE m_GILState;
  };

protected:
  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, FILE *in, FILE *out, FILE *err);

  void LeaveSession();

  void SaveTerminalState(int fd);

  void RestoreTerminalState();

  uint32_t IsExecutingPython() const { return m_lock_count > 0; }

  uint32_t IncrementLockCount() { return ++m_lock_count; }

  uint32_t DecrementLockCount() {
    if (m_lock_count > 0)
      --m_lock_count;
    return m_lock_count;
  }

  enum ActiveIOHandler {
    eIOHandlerNone,
    eIOHandlerBreakpoint,
    eIOHandlerWatchpoint
  };

  PythonObject &GetMainModule();

  PythonDictionary &GetSessionDictionary();

  PythonDictionary &GetSysModuleDictionary();

  bool GetEmbeddedInterpreterModuleObjects();

  bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file,
                    const char *mode);

  PythonFile m_saved_stdin;
  PythonFile m_saved_stdout;
  PythonFile m_saved_stderr;
  PythonObject m_main_module;
  PythonObject m_lldb_module;
  PythonDictionary m_session_dict;
  PythonDictionary m_sys_module_dict;
  PythonObject m_run_one_line_function;
  PythonObject m_run_one_line_str_global;
  std::string m_dictionary_name;
  TerminalState m_terminal_state;
  ActiveIOHandler m_active_io_handler;
  bool m_session_is_active;
  bool m_pty_slave_is_open;
  bool m_valid_session;
  uint32_t m_lock_count;
  PyThreadState *m_command_thread_state;
};

} // namespace lldb_private

#endif // LLDB_DISABLE_PYTHON

#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
