/* Copyright (C) 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 "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 throught 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);

    top_level_interpreter ()->pre_command_loop ();

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

    ui.release ();
  }

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

void _initialize_ui ();
void
_initialize_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);
}
