/* Python DAP interpreter

   Copyright (C) 2022, 2023 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 "defs.h"
#include "python-internal.h"
#include "interps.h"
#include "cli-out.h"
#include "top.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 ();
  }

private:

  std::unique_ptr<ui_out> m_ui_out;
};

void
dap_interp::init (bool top_level)
{
  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 (), "run"));
  if (func == nullptr)
    gdbpy_handle_exception ();

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

  current_ui->input_fd = -1;
  current_ui->m_input_interactive_p = false;
}

void _initialize_py_interp ();
void
_initialize_py_interp ()
{
  interp_factory_register ("dap", [] (const char *name) -> interp *
    {
      return new dap_interp (name);
    });
}
