/* Python DAP interpreter

   Copyright (C) 2022-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "python-internal.h"
#include "interps.h"
#include "cli-out.h"
#include "ui.h"

class dap_interp final : public interp
{
public:

  explicit dap_interp (const char *name)
    : interp (name),
      m_ui_out (new cli_ui_out (gdb_stdout))
  {
  }

  ~dap_interp () override = default;

  void init (bool top_level) override;

  void suspend () override
  {
  }

  void resume () override
  {
  }

  void exec (const char *command) override
  {
    /* Just ignore it.  */
  }

  void set_logging (ui_file_up logfile, bool logging_redirect,
		    bool debug_redirect) override
  {
    /* Just ignore it.  */
  }

  ui_out *interp_ui_out () override
  {
    return m_ui_out.get ();
  }

  void pre_command_loop () override;

  bool supports_new_ui () const override
  { return false; }

private:

  std::unique_ptr<ui_out> m_ui_out;
};


/* Call function FN_NAME from module gdb.dap. */

static void
call_dap_fn (const char *fn_name)
{
  gdbpy_enter enter_py;

  gdbpy_ref<> dap_module (PyImport_ImportModule ("gdb.dap"));
  if (dap_module == nullptr)
    gdbpy_handle_exception ();

  gdbpy_ref<> func (PyObject_GetAttrString (dap_module.get (), fn_name));
  if (func == nullptr)
    gdbpy_handle_exception ();

  gdbpy_ref<> result_obj (PyObject_CallObject (func.get (), nullptr));
  if (result_obj == nullptr)
    gdbpy_handle_exception ();
}

void
dap_interp::init (bool top_level)
{
#if CXX_STD_THREAD
  call_dap_fn ("run");

  current_ui->input_fd = -1;
  current_ui->m_input_interactive_p = false;
#else
  error (_("GDB was compiled without threading, which DAP requires"));
#endif
}

void
dap_interp::pre_command_loop ()
{
  call_dap_fn ("pre_command_loop");
}

void _initialize_py_interp ();
void
_initialize_py_interp ()
{
  /* The dap code uses module typing, available starting python 3.5.  */
#if PY_VERSION_HEX >= 0x03050000
  interp_factory_register ("dap", [] (const char *name) -> interp *
    {
      return new dap_interp (name);
    });
#endif
}
