/* MI Command Set - MI output generating routines for GDB.
   Copyright (C) 2000-2024 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions (a Red Hat company).

   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 MI_MI_OUT_H
#define MI_MI_OUT_H

#include "ui-out.h"
#include <vector>

struct ui_out;
struct ui_file;


class mi_ui_out : public ui_out
{
public:

  explicit mi_ui_out (int mi_version);
  virtual ~mi_ui_out ();

  /* MI-specific */
  void rewind ();
  void put (struct ui_file *stream);

  /* Return the version number of the current MI.  */
  int version ();

  bool can_emit_style_escape () const override
  {
    return false;
  }

  ui_file *current_stream () const override
  { return m_streams.back (); }

protected:

  virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
    override;
  virtual void do_table_body () override;
  virtual void do_table_header (int width, ui_align align,
			     const std::string &col_name,
			     const std::string &col_hdr) override;
  virtual void do_table_end () override;

  virtual void do_begin (ui_out_type type, const char *id) override;
  virtual void do_end (ui_out_type type) override;
  virtual void do_field_signed (int fldno, int width, ui_align align,
				const char *fldname, LONGEST value) override;
  virtual void do_field_unsigned (int fldno, int width, ui_align align,
				  const char *fldname, ULONGEST value)
    override;
  virtual void do_field_skip (int fldno, int width, ui_align align,
			   const char *fldname) override;
  virtual void do_field_string (int fldno, int width, ui_align align,
				const char *fldname, const char *string,
				const ui_file_style &style) override;
  virtual void do_field_fmt (int fldno, int width, ui_align align,
			     const char *fldname, const ui_file_style &style,
			     const char *format, va_list args)
    override ATTRIBUTE_PRINTF (7,0);
  virtual void do_spaces (int numspaces) override;
  virtual void do_text (const char *string) override;
  virtual void do_message (const ui_file_style &style,
			   const char *format, va_list args) override
    ATTRIBUTE_PRINTF (3,0);
  virtual void do_wrap_hint (int indent) override;
  virtual void do_flush () override;
  virtual void do_redirect (struct ui_file *outstream) override;

  virtual bool do_is_mi_like_p () const override
  { return true; }

  virtual void do_progress_start () override;
  virtual void do_progress_notify (const std::string &, const char *,
				   double, double) override;

  virtual void do_progress_end () override;

private:

  void field_separator ();
  void open (const char *name, ui_out_type type);
  void close (ui_out_type type);

  /* The state of a recent progress_update.  */
  struct mi_progress_info
  {
    /* The current state.  */
    progress_update::state state;

    mi_progress_info ()
      : state (progress_update::START)
    {}
  };

  /* Stack of progress info.  */
  std::vector<mi_progress_info> m_progress_info;

  /* Convenience method that returns the MI out's string stream cast
     to its appropriate type.  Assumes/asserts that output was not
     redirected.  */
  string_file *main_stream ();

  /* Helper for the constructor, deduce ui_out_flags for the given
     MI_VERSION.  */
  static ui_out_flags make_flags (int mi_version)
  {
    ui_out_flags flags = 0;

    /* In MI version 2 and below, multi-location breakpoints had a wrong
       syntax.  It is fixed in version 3.  */
    if (mi_version >= 3)
      flags |= fix_multi_location_breakpoint_output;

    /* In MI version 3 and below, the "script" field in breakpoint output
       had a wrong syntax.  It is fixed in version 4.  */
    if (mi_version >= 4)
      flags |= fix_breakpoint_script_output;

    return flags;
  }

  bool m_suppress_field_separator;
  bool m_suppress_output;
  int m_mi_version;
  std::vector<ui_file *> m_streams;
};

/* Create an MI ui-out object with MI version MI_VERSION, which should be equal
   to one of the INTERP_MI* constants (see interps.h).

   Return nullptr if an invalid version is provided.  */
std::unique_ptr<mi_ui_out> mi_out_new (const char *mi_version);

void mi_out_put (ui_out *uiout, struct ui_file *stream);
void mi_out_rewind (ui_out *uiout);

#endif /* MI_MI_OUT_H */
