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

#ifndef UI_H
#define UI_H

#include "gdbsupport/event-loop.h"
#include "gdbsupport/intrusive_list.h"
#include "gdbsupport/next-iterator.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 /* UI_H */
