/* Copyright (C) 2023-2025 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 "ui.h"

#include "cli/cli-cmds.h"
#include "event-top.h"
#include "gdbsupport/buildargv.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/gdb_file.h"
#include "gdbsupport/scoped_fd.h"
#include "interps.h"
#include "pager.h"
#include "main.h"
#include "top.h"

/* See top.h.  */

struct ui *main_ui;
struct ui *current_ui;
struct ui *ui_list;

/* The highest UI number ever assigned.  */

static int highest_ui_num;

/* See top.h.  */

ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
  : num (++highest_ui_num),
    stdin_stream (instream_),
    instream (instream_),
    outstream (outstream_),
    errstream (errstream_),
    input_fd (fileno (instream)),
    m_input_interactive_p (ISATTY (instream)),
    m_gdb_stdout (new pager_file (new stdio_file (outstream))),
    m_gdb_stdin (new stdio_file (instream)),
    m_gdb_stderr (new stderr_file (errstream)),
    m_gdb_stdlog (new timestamped_file (m_gdb_stderr))
{
  unbuffer_stream (instream_);

  if (ui_list == NULL)
    ui_list = this;
  else
    {
      struct ui *last;

      for (last = ui_list; last->next != NULL; last = last->next)
	;
      last->next = this;
    }
}

ui::~ui ()
{
  struct ui *ui, *uiprev;

  uiprev = NULL;

  for (ui = ui_list; ui != NULL; uiprev = ui, ui = ui->next)
    if (ui == this)
      break;

  gdb_assert (ui != NULL);

  if (uiprev != NULL)
    uiprev->next = next;
  else
    ui_list = next;

  delete m_gdb_stdin;
  delete m_gdb_stdout;
  delete m_gdb_stderr;
}


/* Returns whether GDB is running on an interactive terminal.  */

bool
ui::input_interactive_p () const
{
  if (batch_flag)
    return false;

  if (interactive_mode != AUTO_BOOLEAN_AUTO)
    return interactive_mode == AUTO_BOOLEAN_TRUE;

  return m_input_interactive_p;
}


/* When there is an event ready on the stdin file descriptor, instead
   of calling readline directly through the callback function, or
   instead of calling gdb_readline_no_editing_callback, give gdb a
   chance to detect errors and do something.  */

static void
stdin_event_handler (int error, gdb_client_data client_data)
{
  struct ui *ui = (struct ui *) client_data;

  if (error)
    {
      /* Switch to the main UI, so diagnostics always go there.  */
      current_ui = main_ui;

      ui->unregister_file_handler ();
      if (main_ui == ui)
	{
	  /* If stdin died, we may as well kill gdb.  */
	  gdb_printf (gdb_stderr, _("error detected on stdin\n"));
	  quit_command ((char *) 0, 0);
	}
      else
	{
	  /* Simply delete the UI.  */
	  delete ui;
	}
    }
  else
    {
      /* Switch to the UI whose input descriptor woke up the event
	 loop.  */
      current_ui = ui;

      /* This makes sure a ^C immediately followed by further input is
	 always processed in that order.  E.g,. with input like
	 "^Cprint 1\n", the SIGINT handler runs, marks the async
	 signal handler, and then select/poll may return with stdin
	 ready, instead of -1/EINTR.  The
	 gdb.base/double-prompt-target-event-error.exp test exercises
	 this.  */
      QUIT;

      do
	{
	  call_stdin_event_handler_again_p = 0;
	  ui->call_readline (client_data);
	}
      while (call_stdin_event_handler_again_p != 0);
    }
}

/* See top.h.  */

void
ui::register_file_handler ()
{
  if (input_fd != -1)
    add_file_handler (input_fd, stdin_event_handler, this,
		      string_printf ("ui-%d", num), true);
}

/* See top.h.  */

void
ui::unregister_file_handler ()
{
  if (input_fd != -1)
    delete_file_handler (input_fd);
}

/* Open file named NAME for read/write, making sure not to make it the
   controlling terminal.  */

static gdb_file_up
open_terminal_stream (const char *name)
{
  scoped_fd fd = gdb_open_cloexec (name, O_RDWR | O_NOCTTY, 0);
  if (fd.get () < 0)
    perror_with_name  (_("opening terminal failed"));

  return fd.to_file ("w+");
}

/* Implementation of the "new-ui" command.  */

static void
new_ui_command (const char *args, int from_tty)
{
  int argc;
  const char *interpreter_name;
  const char *tty_name;

  dont_repeat ();

  gdb_argv argv (args);
  argc = argv.count ();

  if (argc < 2)
    error (_("Usage: new-ui INTERPRETER TTY"));

  interpreter_name = argv[0];
  tty_name = argv[1];

  {
    scoped_restore save_ui = make_scoped_restore (&current_ui);

    /* Open specified terminal.  Note: we used to open it three times,
       once for each of stdin/stdout/stderr, but that does not work
       with Windows named pipes.  */
    gdb_file_up stream = open_terminal_stream (tty_name);

    std::unique_ptr<ui> ui
      (new struct ui (stream.get (), stream.get (), stream.get ()));

    ui->async = 1;

    current_ui = ui.get ();

    set_top_level_interpreter (interpreter_name, true);

    top_level_interpreter ()->pre_command_loop ();

    /* Make sure the file is not closed.  */
    stream.release ();

    ui.release ();
  }

  gdb_printf ("New UI allocated\n");
}

INIT_GDB_FILE (ui)
{
  cmd_list_element *c = add_cmd ("new-ui", class_support, new_ui_command, _("\
Create a new UI.\n\
Usage: new-ui INTERPRETER TTY\n\
The first argument is the name of the interpreter to run.\n\
The second argument is the terminal the UI runs on."), &cmdlist);
  set_cmd_completer (c, interpreter_completer);
}
