/* 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 "ui.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 ();
}
