/* Output generating routines for GDB CLI.

   Copyright (C) 1999-2023 Free Software Foundation, Inc.

   Contributed by Cygnus Solutions.
   Written by Fernando Nasser for Cygnus.

   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-out.h"
#include "cli-out.h"
#include "completer.h"
#include "readline/readline.h"
#include "cli/cli-style.h"
#include "top.h"

/* These are the CLI output functions */

/* Mark beginning of a table */

void
cli_ui_out::do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
{
  if (nr_rows == 0)
    m_suppress_output = true;
  else
    /* Only the table suppresses the output and, fortunately, a table
       is not a recursive data structure.  */
    gdb_assert (!m_suppress_output);
}

/* Mark beginning of a table body */

void
cli_ui_out::do_table_body ()
{
  if (m_suppress_output)
    return;

  /* first, close the table header line */
  text ("\n");
}

/* Mark end of a table */

void
cli_ui_out::do_table_end ()
{
  m_suppress_output = false;
}

/* Specify table header */

void
cli_ui_out::do_table_header (int width, ui_align alignment,
			     const std::string &col_name,
			     const std::string &col_hdr)
{
  if (m_suppress_output)
    return;

  do_field_string (0, width, alignment, 0, col_hdr.c_str (),
		   ui_file_style ());
}

/* Mark beginning of a list */

void
cli_ui_out::do_begin (ui_out_type type, const char *id)
{
}

/* Mark end of a list */

void
cli_ui_out::do_end (ui_out_type type)
{
}

/* output an int field */

void
cli_ui_out::do_field_signed (int fldno, int width, ui_align alignment,
			     const char *fldname, LONGEST value)
{
  if (m_suppress_output)
    return;

  do_field_string (fldno, width, alignment, fldname, plongest (value),
		   ui_file_style ());
}

/* output an unsigned field */

void
cli_ui_out::do_field_unsigned (int fldno, int width, ui_align alignment,
			       const char *fldname, ULONGEST value)
{
  if (m_suppress_output)
    return;

  do_field_string (fldno, width, alignment, fldname, pulongest (value),
		   ui_file_style ());
}

/* used to omit a field */

void
cli_ui_out::do_field_skip (int fldno, int width, ui_align alignment,
			   const char *fldname)
{
  if (m_suppress_output)
    return;

  do_field_string (fldno, width, alignment, fldname, "",
		   ui_file_style ());
}

/* other specific cli_field_* end up here so alignment and field
   separators are both handled by cli_field_string */

void
cli_ui_out::do_field_string (int fldno, int width, ui_align align,
			     const char *fldname, const char *string,
			     const ui_file_style &style)
{
  int before = 0;
  int after = 0;

  if (m_suppress_output)
    return;

  if ((align != ui_noalign) && string)
    {
      before = width - strlen (string);
      if (before <= 0)
	before = 0;
      else
	{
	  if (align == ui_right)
	    after = 0;
	  else if (align == ui_left)
	    {
	      after = before;
	      before = 0;
	    }
	  else
	    /* ui_center */
	    {
	      after = before / 2;
	      before -= after;
	    }
	}
    }

  if (before)
    spaces (before);

  if (string)
    {
      ui_file *stream = m_streams.back ();
      stream->emit_style_escape (style);
      stream->puts (string);
      stream->emit_style_escape (ui_file_style ());
    }

  if (after)
    spaces (after);

  if (align != ui_noalign)
    field_separator ();
}

/* Output field containing ARGS using printf formatting in FORMAT.  */

void
cli_ui_out::do_field_fmt (int fldno, int width, ui_align align,
			  const char *fldname, const ui_file_style &style,
			  const char *format, va_list args)
{
  if (m_suppress_output)
    return;

  std::string str = string_vprintf (format, args);

  do_field_string (fldno, width, align, fldname, str.c_str (), style);
}

void
cli_ui_out::do_spaces (int numspaces)
{
  if (m_suppress_output)
    return;

  print_spaces (numspaces, m_streams.back ());
}

void
cli_ui_out::do_text (const char *string)
{
  if (m_suppress_output)
    return;

  gdb_puts (string, m_streams.back ());
}

void
cli_ui_out::do_message (const ui_file_style &style,
			const char *format, va_list args)
{
  if (m_suppress_output)
    return;

  std::string str = string_vprintf (format, args);
  if (!str.empty ())
    {
      ui_file *stream = m_streams.back ();
      stream->emit_style_escape (style);
      stream->puts (str.c_str ());
      stream->emit_style_escape (ui_file_style ());
    }
}

void
cli_ui_out::do_wrap_hint (int indent)
{
  if (m_suppress_output)
    return;

  m_streams.back ()->wrap_here (indent);
}

void
cli_ui_out::do_flush ()
{
  gdb_flush (m_streams.back ());
}

/* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams
   and make it therefore active.  OUTSTREAM as NULL will pop the last pushed
   output stream; it is an internal error if it does not exist.  */

void
cli_ui_out::do_redirect (ui_file *outstream)
{
  if (outstream != NULL)
    m_streams.push_back (outstream);
  else
    m_streams.pop_back ();
}

/* Initialize a progress update to be displayed with
   cli_ui_out::do_progress_notify.  */

void
cli_ui_out::do_progress_start ()
{
  m_progress_info.emplace_back ();
}

#define MIN_CHARS_PER_LINE 50
#define MAX_CHARS_PER_LINE 4096

/* Print a progress update.  MSG is a string to be printed on the line above
   the progress bar.  TOTAL is the size of the download whose progress is
   being displayed.  UNIT should be the unit of TOTAL (ex. "K"). If HOWMUCH
   is between 0.0 and 1.0, a progress bar is displayed indicating the percentage
   of completion and the download size.  If HOWMUCH is negative, a progress
   indicator will tick across the screen.  If the output stream is not a tty
   then only MSG is printed.

   - printed for tty, HOWMUCH between 0.0 and 1.0:
	<MSG
	[#########                  ]  HOWMUCH*100% (TOTAL UNIT)\r>
   - printed for tty, HOWMUCH < 0.0:
	<MSG
	[    ###                    ]\r>
   - printed for not-a-tty:
	<MSG...\n>
*/

void
cli_ui_out::do_progress_notify (const std::string &msg,
				const char *unit,
				double howmuch, double total)
{
  int chars_per_line = get_chars_per_line ();
  struct ui_file *stream = m_streams.back ();
  cli_progress_info &info (m_progress_info.back ());

  if (chars_per_line > MAX_CHARS_PER_LINE)
    chars_per_line = MAX_CHARS_PER_LINE;

  if (info.state == progress_update::START)
    {
      if (stream->isatty ()
	  && current_ui->input_interactive_p ()
	  && chars_per_line >= MIN_CHARS_PER_LINE)
	{
	  gdb_printf (stream, "%s\n", msg.c_str ());
	  info.state = progress_update::BAR;
	}
      else
	{
	  gdb_printf (stream, "%s...\n", msg.c_str ());
	  info.state = progress_update::WORKING;
	}
    }

  if (info.state != progress_update::BAR
      || chars_per_line < MIN_CHARS_PER_LINE)
    return;

  if (total > 0 && howmuch >= 0 && howmuch <= 1.0)
    {
      std::string progress = string_printf (" %3.f%% (%.2f %s)",
					    howmuch * 100, total,
					    unit);
      int width = chars_per_line - progress.size () - 4;
      int max = width * howmuch;

      std::string display = "\r[";

      for (int i = 0; i < width; ++i)
	if (i < max)
	  display += "#";
	else
	  display += " ";

      display += "]" + progress;
      gdb_printf (stream, "%s", display.c_str ());
      gdb_flush (stream);
    }
  else
    {
      using namespace std::chrono;
      milliseconds diff = duration_cast<milliseconds>
	(steady_clock::now () - info.last_update);

      /* Advance the progress indicator at a rate of 1 tick every
	 every 0.5 seconds.  */
      if (diff.count () >= 500)
	{
	  int width = chars_per_line - 4;

	  gdb_printf (stream, "\r[");
	  for (int i = 0; i < width; ++i)
	    {
	      if (i == info.pos % width
		  || i == (info.pos + 1) % width
		  || i == (info.pos + 2) % width)
		gdb_printf (stream, "#");
	      else
		gdb_printf (stream, " ");
	    }

	  gdb_printf (stream, "]");
	  gdb_flush (stream);
	  info.last_update = steady_clock::now ();
	  info.pos++;
	}
    }

  return;
}

/* Clear the current line of the most recent progress update.  Overwrites
   the current line with whitespace.  */

void
cli_ui_out::clear_current_line ()
{
  struct ui_file *stream = m_streams.back ();
  int chars_per_line = get_chars_per_line ();

  if (!stream->isatty ()
      || !current_ui->input_interactive_p ()
      || chars_per_line < MIN_CHARS_PER_LINE)
    return;

  if (chars_per_line > MAX_CHARS_PER_LINE)
    chars_per_line = MAX_CHARS_PER_LINE;

  gdb_printf (stream, "\r");
  for (int i = 0; i < chars_per_line; ++i)
    gdb_printf (stream, " ");
  gdb_printf (stream, "\r");

  gdb_flush (stream);
}

/* Remove the most recent progress update from the progress_info stack
   and overwrite the current line with whitespace.  */

void
cli_ui_out::do_progress_end ()
{
  struct ui_file *stream = m_streams.back ();
  m_progress_info.pop_back ();

  if (stream->isatty ())
    clear_current_line ();
}

/* local functions */

void
cli_ui_out::field_separator ()
{
  gdb_putc (' ', m_streams.back ());
}

/* Constructor for cli_ui_out.  */

cli_ui_out::cli_ui_out (ui_file *stream, ui_out_flags flags)
: ui_out (flags),
  m_suppress_output (false)
{
  gdb_assert (stream != NULL);

  m_streams.push_back (stream);
}

cli_ui_out::~cli_ui_out ()
{
}

ui_file *
cli_ui_out::set_stream (struct ui_file *stream)
{
  ui_file *old;

  old = m_streams.back ();
  m_streams.back () = stream;

  return old;
}

bool
cli_ui_out::can_emit_style_escape () const
{
  return m_streams.back ()->can_emit_style_escape ();
}

/* CLI interface to display tab-completion matches.  */

/* CLI version of displayer.crlf.  */

static void
cli_mld_crlf (const struct match_list_displayer *displayer)
{
  rl_crlf ();
}

/* CLI version of displayer.putch.  */

static void
cli_mld_putch (const struct match_list_displayer *displayer, int ch)
{
  putc (ch, rl_outstream);
}

/* CLI version of displayer.puts.  */

static void
cli_mld_puts (const struct match_list_displayer *displayer, const char *s)
{
  fputs (s, rl_outstream);
}

/* CLI version of displayer.flush.  */

static void
cli_mld_flush (const struct match_list_displayer *displayer)
{
  fflush (rl_outstream);
}

EXTERN_C void _rl_erase_entire_line (void);

/* CLI version of displayer.erase_entire_line.  */

static void
cli_mld_erase_entire_line (const struct match_list_displayer *displayer)
{
  _rl_erase_entire_line ();
}

/* CLI version of displayer.beep.  */

static void
cli_mld_beep (const struct match_list_displayer *displayer)
{
  rl_ding ();
}

/* CLI version of displayer.read_key.  */

static int
cli_mld_read_key (const struct match_list_displayer *displayer)
{
  return rl_read_key ();
}

/* CLI version of rl_completion_display_matches_hook.
   See gdb_display_match_list for a description of the arguments.  */

void
cli_display_match_list (char **matches, int len, int max)
{
  struct match_list_displayer displayer;

  rl_get_screen_size (&displayer.height, &displayer.width);
  displayer.crlf = cli_mld_crlf;
  displayer.putch = cli_mld_putch;
  displayer.puts = cli_mld_puts;
  displayer.flush = cli_mld_flush;
  displayer.erase_entire_line = cli_mld_erase_entire_line;
  displayer.beep = cli_mld_beep;
  displayer.read_key = cli_mld_read_key;

  gdb_display_match_list (matches, len, max, &displayer);
  rl_forced_update_display ();
}
