/* 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/>.  */

#ifndef GDB_UI_H
#define GDB_UI_H

#include "gdbsupport/event-loop.h"
#include "gdbsupport/intrusive_list.h"
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/scoped_restore.h"

struct interp;

/* Prompt state.  */

enum prompt_state
{
  /* The command line is blocked simulating synchronous execution.
     This is used to implement the foreground execution commands
     ('run', 'continue', etc.).  We won't display the prompt and
     accept further commands until the execution is actually over.  */
  PROMPT_BLOCKED,

  /* The command finished; display the prompt before returning back to
     the top level.  */
  PROMPT_NEEDED,

  /* We've displayed the prompt already, ready for input.  */
  PROMPTED,
};

/* All about a user interface instance.  Each user interface has its
   own I/O files/streams, readline state, its own top level
   interpreter (for the main UI, this is the interpreter specified
   with -i on the command line) and secondary interpreters (for
   interpreter-exec ...), etc.  There's always one UI associated with
   stdin/stdout/stderr, but the user can create secondary UIs, for
   example, to create a separate MI channel on its own stdio
   streams.  */

struct ui
{
  /* Create a new UI.  */
  ui (FILE *instream, FILE *outstream, FILE *errstream);
  ~ui ();

  DISABLE_COPY_AND_ASSIGN (ui);

  /* Pointer to next in singly-linked list.  */
  struct ui *next = nullptr;

  /* Convenient handle (UI number).  Unique across all UIs.  */
  int num;

  /* The UI's command line buffer.  This is to used to accumulate
     input until we have a whole command line.  */
  std::string line_buffer;

  /* The callback used by the event loop whenever an event is detected
     on the UI's input file descriptor.  This function incrementally
     builds a buffer where it accumulates the line read up to the
     point of invocation.  In the special case in which the character
     read is newline, the function invokes the INPUT_HANDLER callback
     (see below).  */
  void (*call_readline) (gdb_client_data) = nullptr;

  /* The function to invoke when a complete line of input is ready for
     processing.  */
  void (*input_handler) (gdb::unique_xmalloc_ptr<char> &&) = nullptr;

  /* True if this UI is using the readline library for command
     editing; false if using GDB's own simple readline emulation, with
     no editing support.  */
  int command_editing = 0;

  /* Each UI has its own independent set of interpreters.  */
  intrusive_list<interp> interp_list;
  interp *current_interpreter = nullptr;
  interp *top_level_interpreter = nullptr;

  /* The interpreter that is active while `interp_exec' is active, NULL
     at all other times.  */
  interp *command_interpreter = nullptr;

  /* True if the UI is in async mode, false if in sync mode.  If in
     sync mode, a synchronous execution command (e.g, "next") does not
     return until the command is finished.  If in async mode, then
     running a synchronous command returns right after resuming the
     target.  Waiting for the command's completion is later done on
     the top event loop.  For the main UI, this starts out disabled,
     until all the explicit command line arguments (e.g., `gdb -ex
     "start" -ex "next"') are processed.  */
  int async = 0;

  /* The number of nested readline secondary prompts that are
     currently active.  */
  int secondary_prompt_depth = 0;

  /* The UI's stdin.  Set to stdin for the main UI.  */
  FILE *stdin_stream;

  /* stdio stream that command input is being read from.  Set to stdin
     normally.  Set by source_command to the file we are sourcing.
     Set to NULL if we are executing a user-defined command or
     interacting via a GUI.  */
  FILE *instream;
  /* Standard output stream.  */
  FILE *outstream;
  /* Standard error stream.  */
  FILE *errstream;

  /* The file descriptor for the input stream, so that we can register
     it with the event loop.  This can be set to -1 to prevent this
     registration.  */
  int input_fd;

  /* Whether ISATTY returns true on input_fd.  Cached here because
     quit_force needs to know this _after_ input_fd might be
     closed.  */
  bool m_input_interactive_p;

  /* See enum prompt_state's description.  */
  enum prompt_state prompt_state = PROMPT_NEEDED;

  /* Whether the prompt should be kept blocked.  This is useful to not
     unblock the prompt too early in the context of nested command
     execution.  */
  bool keep_prompt_blocked = false;

  /* The fields below that start with "m_" are "private".  They're
     meant to be accessed through wrapper macros that make them look
     like globals.  */

  /* The ui_file streams.  */
  /* Normal results */
  struct ui_file *m_gdb_stdout;
  /* Input stream */
  struct ui_file *m_gdb_stdin;
  /* Serious error notifications */
  struct ui_file *m_gdb_stderr;
  /* Log/debug/trace messages that should bypass normal stdout/stderr
     filtering.  */
  struct ui_file *m_gdb_stdlog;

  /* The current ui_out.  */
  struct ui_out *m_current_uiout = nullptr;

  /* Register the UI's input file descriptor in the event loop.  */
  void register_file_handler ();

  /* Unregister the UI's input file descriptor from the event loop.  */
  void unregister_file_handler ();

  /* Return true if this UI's input fd is a tty.  */
  bool input_interactive_p () const;
};

/* The main UI.  This is the UI that is bound to stdin/stdout/stderr.
   It always exists and is created automatically when GDB starts
   up.  */
extern struct ui *main_ui;

/* The current UI.  */
extern struct ui *current_ui;

/* The list of all UIs.  */
extern struct ui *ui_list;

/* State for SWITCH_THRU_ALL_UIS.  */
class switch_thru_all_uis
{
public:

  switch_thru_all_uis () : m_iter (ui_list), m_save_ui (&current_ui)
  {
    current_ui = ui_list;
  }

  DISABLE_COPY_AND_ASSIGN (switch_thru_all_uis);

  /* If done iterating, return true; otherwise return false.  */
  bool done () const
  {
    return m_iter == NULL;
  }

  /* Move to the next UI, setting current_ui if iteration is not yet
     complete.  */
  void next ()
  {
    m_iter = m_iter->next;
    if (m_iter != NULL)
      current_ui = m_iter;
  }

 private:

  /* Used to iterate through the UIs.  */
  struct ui *m_iter;

  /* Save and restore current_ui.  */
  scoped_restore_tmpl<struct ui *> m_save_ui;
};

  /* Traverse through all UI, and switch the current UI to the one
     being iterated.  */
#define SWITCH_THRU_ALL_UIS()		\
  for (switch_thru_all_uis stau_state; !stau_state.done (); stau_state.next ())

using ui_range = next_range<ui>;

/* An adapter that can be used to traverse over all UIs.  */
static inline
ui_range all_uis ()
{
  return ui_range (ui_list);
}

#endif /* GDB_UI_H */
