/* A C++ wrapper API around libgdiagnostics.h for emitting diagnostics.
   Copyright (C) 2023-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef LIBGDIAGNOSTICSPP_H
#define LIBGDIAGNOSTICSPP_H

#include "libgdiagnostics.h"

namespace libgdiagnostics {

typedef diagnostic_line_num_t line_num_t;
typedef diagnostic_column_num_t column_num_t;

class file;
class physical_location;
class logical_location;
class execution_path;
class group;
class manager;
class diagnostic;
class graph;
class node;
class edge;
class message_buffer;

/* Wrapper around a borrowed diagnostic_text_sink *.  */

class text_sink
{
public:
  text_sink (diagnostic_text_sink *inner)
  : m_inner (inner)
  {
  }

  void
  set_source_printing_enabled (int value)
  {
    diagnostic_text_sink_set_source_printing_enabled (m_inner, value);
  }

  void
  set_colorize (enum diagnostic_colorize colorize)
  {
    diagnostic_text_sink_set_colorize (m_inner, colorize);
  }

  void
  set_labelled_source_colorization_enabled (int value)
  {
    diagnostic_text_sink_set_labelled_source_colorization_enabled (m_inner,
								   value);
  }

  diagnostic_text_sink *m_inner;
};

/* Wrapper around a diagnostic_file *.  */

class file
{
public:
  file () : m_inner (nullptr) {}
  file (diagnostic_file *file) : m_inner (file) {}
  file (const file &other) : m_inner (other.m_inner) {}
  file &operator= (const file &other) { m_inner = other.m_inner; return *this; }

  void set_buffered_content (const char *data, size_t sz);

  diagnostic_file * m_inner;
};

/* Wrapper around a const diagnostic_physical_location *.  */

class physical_location
{
public:
  physical_location () : m_inner (nullptr) {}

  physical_location (const diagnostic_physical_location *location)
  : m_inner (location)
  {}

  file get_file () const;

  const diagnostic_physical_location *m_inner;
};

/* Wrapper around a const diagnostic_logical_location *.  */

class logical_location
{
public:
  logical_location () : m_inner (nullptr) {}

  logical_location (const diagnostic_logical_location *logical_loc)
  : m_inner (logical_loc)
  {}

  operator bool() { return m_inner != nullptr; }

  // Various accessors
  enum diagnostic_logical_location_kind_t get_kind () const;
  logical_location get_parent () const;
  const char *get_short_name () const;
  const char *get_fully_qualified_name () const;
  const char *get_decorated_name () const;

  bool operator== (const logical_location &other) const
  {
    return m_inner == other.m_inner;
  }

  bool operator!= (const logical_location &other) const
  {
    return m_inner != other.m_inner;
  }

  const diagnostic_logical_location *m_inner;
};

/* Wrapper around a diagnostic_message_buffer *, with ownership.  */

class message_buffer
{
public:
  message_buffer () : m_inner (nullptr) {}
  message_buffer (diagnostic_message_buffer *inner) : m_inner (inner) {}
  ~message_buffer ()
  {
    if (m_inner)
      diagnostic_message_buffer_release (m_inner);
  }
  message_buffer (const message_buffer &) = delete;
  message_buffer (message_buffer &&other)
  {
    m_inner = other.m_inner;
    other.m_inner = nullptr;
  }
  message_buffer& operator= (const message_buffer &) = delete;
  message_buffer& operator= (message_buffer &&other)
  {
    if (m_inner)
      diagnostic_message_buffer_release (m_inner);
    m_inner = other.m_inner;
    other.m_inner = nullptr;
    return *this;
  }

  message_buffer&
  operator+= (const char *str)
  {
    diagnostic_message_buffer_append_str (m_inner, str);
    return *this;
  }

  message_buffer&
  operator+= (char ch)
  {
    diagnostic_message_buffer_append_byte (m_inner, ch);
    return *this;
  }

  message_buffer &
  begin_url (const char *url)
  {
    diagnostic_message_buffer_begin_url (m_inner, url);
    return *this;
  }

  message_buffer &
  end_url ()
  {
    diagnostic_message_buffer_end_url (m_inner);
    return *this;
  }

  diagnostic_message_buffer *m_inner;
};

/* RAII class around a diagnostic_execution_path *.  */

class execution_path
{
public:
  execution_path () : m_inner (nullptr), m_owned (false) {}

  execution_path (diagnostic_execution_path *path)
  : m_inner (path), m_owned (true)
  {}

  execution_path (const diagnostic_execution_path *path)
  : m_inner (const_cast<diagnostic_execution_path *> (path)),
    m_owned (false)
  {}

  execution_path (const execution_path &other) = delete;
  execution_path &operator= (const execution_path &other) = delete;

  execution_path (execution_path &&other)
  : m_inner (other.m_inner),
    m_owned (other.m_owned)
  {
    other.m_inner = nullptr;
    other.m_owned = false;
  }

  execution_path &operator= (execution_path &&other)
  {
    m_inner = other.m_inner;
    m_owned = other.m_owned;
    other.m_inner = nullptr;
    other.m_owned = false;
    return *this;
  }

  ~execution_path ()
  {
    if (m_owned)
      diagnostic_execution_path_release (m_inner);
  }

  diagnostic_event_id
  add_event (physical_location physical_loc,
	     logical_location logical_loc,
	     unsigned stack_depth,
	     const char *fmt, ...)
    LIBGDIAGNOSTICS_PARAM_GCC_FORMAT_STRING (5, 6);

  diagnostic_event_id
  add_event_va (physical_location physical_loc,
		logical_location logical_loc,
		unsigned stack_depth,
		const char *fmt,
		va_list *args)
    LIBGDIAGNOSTICS_PARAM_GCC_FORMAT_STRING (5, 0);

  diagnostic_event_id
  add_event_via_msg_buf (physical_location physical_loc,
			 logical_location logical_loc,
			 unsigned stack_depth,
			 message_buffer &&msg_buf);

  diagnostic_execution_path *m_inner;
  bool m_owned;
};

/* RAII class for starting/ending a group within a diagnostic_manager.  */

class group
{
public:
  group (manager &mgr);
  ~group ();

private:
  manager &m_mgr;
};

/* Wrapper around a diagnostic *.  */

class diagnostic
{
public:
  diagnostic (::diagnostic *d) : m_inner (d) {}

  void
  set_cwe (unsigned cwe_id);

  void
  add_rule (const char *title, const char *url);

  void
  set_location (physical_location loc);

  void
  add_location (physical_location loc);

  void
  add_location_with_label (physical_location loc,
			   const char *text);

  void
  add_location_with_label (physical_location loc,
			   message_buffer &&text);

  void
  set_logical_location (logical_location loc);

  void
  add_fix_it_hint_insert_before (physical_location loc,
				 const char *addition);
  void
  add_fix_it_hint_insert_after (physical_location loc,
				const char *addition);
  void
  add_fix_it_hint_replace (physical_location loc,
			   const char *replacement);
  void
  add_fix_it_hint_delete (physical_location loc);

  void
  take_execution_path (execution_path path);

  void
  take_graph (graph g);

  void
  finish (const char *fmt, ...)
    LIBGDIAGNOSTICS_PARAM_MUST_BE_NON_NULL (2)
    LIBGDIAGNOSTICS_PARAM_GCC_FORMAT_STRING (2, 3);

  void
  finish_va (const char *fmt, va_list *args)
    LIBGDIAGNOSTICS_PARAM_MUST_BE_NON_NULL (2)
    LIBGDIAGNOSTICS_PARAM_GCC_FORMAT_STRING (2, 0);

  void
  finish_via_msg_buf (message_buffer &&msg_buf);

  ::diagnostic * const m_inner;
};

/* Wrapper around a diagnostic_manager *, possibly with ownership.  */

class manager
{
public:
  manager ()
  : m_inner (diagnostic_manager_new ()),
    m_owned (true)
  {
  }
  manager (diagnostic_manager *inner, bool owned)
  : m_inner (inner),
    m_owned (owned)
  {
  }
  ~manager ()
  {
    if (m_owned)
      diagnostic_manager_release (m_inner);
  }

  manager (const manager &other) = delete;
  manager (manager &&other)
  : m_inner (other.m_inner),
    m_owned (other.m_owned)
  {
    other.m_inner = nullptr;
  }

  void
  set_tool_name (const char *value)
  {
    diagnostic_manager_set_tool_name (m_inner, value);
  }

  void
  set_full_name (const char *value)
  {
    diagnostic_manager_set_full_name (m_inner, value);
  }

  void
  set_version_string (const char *value)
  {
    diagnostic_manager_set_version_string (m_inner, value);
  }

  void
  set_version_url (const char *value)
  {
    diagnostic_manager_set_version_url (m_inner, value);
  }

  text_sink
  add_text_sink (FILE *dst_stream,
		 enum diagnostic_colorize colorize)
  {
    return text_sink
      (diagnostic_manager_add_text_sink (m_inner, dst_stream, colorize));
  }

  void
  add_sarif_sink (FILE *dst_stream,
		  file main_input_file,
		  enum diagnostic_sarif_version version)
  {
    diagnostic_manager_add_sarif_sink (m_inner, dst_stream,
				       main_input_file.m_inner,
				       version);
  }

  bool
  add_sink_from_spec (const char *option_name,
		      const char *spec,
		      manager control_mgr)
  {
    return diagnostic_manager_add_sink_from_spec (m_inner,
						  option_name,
						  spec,
						  control_mgr.m_inner);
  }

  void
  write_patch (FILE *dst_stream)
  {
    diagnostic_manager_write_patch (m_inner, dst_stream);
  }

  /* Location management.  */

  file
  new_file (const char *name,
	    const char *sarif_source_language)
    LIBGDIAGNOSTICS_PARAM_MUST_BE_NON_NULL (2)
    LIBGDIAGNOSTICS_PARAM_CAN_BE_NULL (3);

  void
  debug_dump (file f,
	      FILE *out);

  physical_location
  new_location_from_file_and_line (file f, diagnostic_line_num_t line_num);

  physical_location
  new_location_from_file_line_column (file f,
				      line_num_t line_num,
				      column_num_t column_num);

  physical_location
  new_location_from_range (physical_location loc_caret,
			   physical_location loc_start,
			   physical_location loc_end);

  void
  debug_dump (physical_location loc,
	      FILE *out);

  logical_location
  new_logical_location (enum diagnostic_logical_location_kind_t kind,
			logical_location parent,
			const char *short_name,
			const char *fully_qualified_name,
			const char *decorated_name);

  void
  debug_dump (logical_location loc,
	      FILE *out);

  execution_path
  new_execution_path ();

  diagnostic
  begin_diagnostic (enum diagnostic_level level);

  void
  set_analysis_target (file f);

  void
  take_global_graph (graph g);

  diagnostic_manager *m_inner;
  bool m_owned;
};

class graph
{
public:
  graph () : m_inner (nullptr), m_owned (false) {}

  graph (diagnostic_graph *graph)
  : m_inner (graph), m_owned (true)
  {}

  graph (const diagnostic_graph *graph)
  : m_inner (const_cast<diagnostic_graph *> (graph)),
    m_owned (false)
  {}

  graph (const graph &other) = delete;
  graph &operator= (const graph &other) = delete;

  graph (graph &&other)
  : m_inner (other.m_inner),
    m_owned (other.m_owned)
  {
    other.m_inner = nullptr;
    other.m_owned = false;
  }

  graph &operator= (graph &&other)
  {
    m_inner = other.m_inner;
    m_owned = other.m_owned;
    other.m_inner = nullptr;
    other.m_owned = false;
    return *this;
  }

  ~graph ()
  {
    if (m_owned)
      diagnostic_graph_release (m_inner);
  }

  void
  set_description (const char *);
  void
  set_description (message_buffer &&);

  node
  get_node_by_id (const char *id) const;

  edge
  get_edge_by_id (const char *id) const;

  edge
  add_edge (const char *id, node src_node, node dst_node, const char *label);
  edge
  add_edge (const char *id, node src_node, node dst_node, message_buffer &&label);

  diagnostic_graph *m_inner;
  bool m_owned;
};

// Borrowed pointer to a diagnostic_node.

class node
{
public:
  node () : m_inner (nullptr) {}
  node (diagnostic_node *node_) : m_inner (node_) {}

  void
  set_label (const char *);
  void
  set_label (message_buffer &&);

  void
  set_location (physical_location loc);

  void
  set_logical_location (logical_location loc);

  diagnostic_node *m_inner;
};

// Borrowed edge to a diagnostic_edge.

class edge
{
public:
  edge (diagnostic_edge *edge_) : m_inner (edge_) {}

  diagnostic_edge *m_inner;
};

// Implementation

// class file

inline void
file::set_buffered_content (const char *data, size_t sz)
{
  diagnostic_file_set_buffered_content (m_inner, data, sz);
}

// class physical_location

inline file
physical_location::get_file () const
{
  return file (diagnostic_physical_location_get_file (m_inner));
}

// class logical_location

inline enum diagnostic_logical_location_kind_t
logical_location::get_kind () const
{
  // m_inner must be non-null
  return diagnostic_logical_location_get_kind (m_inner);
}

inline logical_location
logical_location::get_parent () const
{
  if (m_inner)
    return diagnostic_logical_location_get_parent (m_inner);
  else
    return nullptr;
}

inline const char *
logical_location::get_short_name () const
{
  if (m_inner)
    return diagnostic_logical_location_get_short_name (m_inner);
  else
    return nullptr;
}

inline const char *
logical_location::get_fully_qualified_name () const
{
  if (m_inner)
    return diagnostic_logical_location_get_fully_qualified_name (m_inner);
  else
    return nullptr;
}

inline const char *
logical_location::get_decorated_name () const
{
  if (m_inner)
    return diagnostic_logical_location_get_decorated_name (m_inner);
  else
    return nullptr;
}

// class execution_path

inline diagnostic_event_id
execution_path::add_event (physical_location physical_loc,
			   logical_location logical_loc,
			   unsigned stack_depth,
			   const char *fmt, ...)
{
  va_list args;
  va_start (args, fmt);
  diagnostic_event_id result = add_event_va (physical_loc,
					     logical_loc,
					     stack_depth,
					     fmt, &args);
  va_end (args);

  return result;
}

inline diagnostic_event_id
execution_path::add_event_va (physical_location physical_loc,
			      logical_location logical_loc,
			      unsigned stack_depth,
			      const char *fmt,
			      va_list *args)
{
  return diagnostic_execution_path_add_event_va (m_inner,
						 physical_loc.m_inner,
						 logical_loc.m_inner,
						 stack_depth,
						 fmt,
						 args);
}

inline diagnostic_event_id
execution_path::add_event_via_msg_buf (physical_location physical_loc,
				       logical_location logical_loc,
				       unsigned stack_depth,
				       message_buffer &&msg_buf)
{
  diagnostic_message_buffer *inner_msg_buf = msg_buf.m_inner;
  msg_buf.m_inner = nullptr;
  return diagnostic_execution_path_add_event_via_msg_buf (m_inner,
							  physical_loc.m_inner,
							  logical_loc.m_inner,
							  stack_depth,
							  inner_msg_buf);
}

// class group

inline
group::group (manager &mgr)
: m_mgr (mgr)
{
  diagnostic_manager_begin_group (m_mgr.m_inner);
}

inline
group::~group ()
{
  diagnostic_manager_end_group (m_mgr.m_inner);
}

// class diagnostic

inline void
diagnostic::set_cwe (unsigned cwe_id)
{
  diagnostic_set_cwe (m_inner, cwe_id);
}

inline void
diagnostic::add_rule (const char *title, const char *url)
{
  diagnostic_add_rule (m_inner, title, url);
}

inline void
diagnostic::set_location (physical_location loc)
{
  diagnostic_set_location (m_inner, loc.m_inner);
}

inline void
diagnostic::add_location_with_label (physical_location loc,
				     const char *text)
{
  diagnostic_add_location_with_label (m_inner, loc.m_inner, text);
}

inline void
diagnostic::add_location_with_label (physical_location loc,
				     message_buffer &&msg_buf)
{
  diagnostic_message_buffer *inner_msg_buf = msg_buf.m_inner;
  msg_buf.m_inner = nullptr;
  diagnostic_add_location_with_label_via_msg_buf (m_inner,
						  loc.m_inner,
						  inner_msg_buf);
}

inline void
diagnostic::add_location (physical_location loc)
{
  diagnostic_add_location (m_inner, loc.m_inner);
}

inline void
diagnostic::set_logical_location (logical_location loc)
{
  diagnostic_set_logical_location (m_inner, loc.m_inner);
}

inline void
diagnostic::add_fix_it_hint_insert_before (physical_location loc,
					   const char *addition)
{
  diagnostic_add_fix_it_hint_insert_before (m_inner,
					    loc.m_inner,
					    addition);
}

inline void
diagnostic::add_fix_it_hint_insert_after (physical_location loc,
				const char *addition)
{
  diagnostic_add_fix_it_hint_insert_after (m_inner,
					   loc.m_inner,
					   addition);
}

inline void
diagnostic::add_fix_it_hint_replace (physical_location loc,
				     const char *replacement)
{
  diagnostic_add_fix_it_hint_replace (m_inner,
				      loc.m_inner,
				      replacement);
}

inline void
diagnostic::add_fix_it_hint_delete (physical_location loc)
{
  diagnostic_add_fix_it_hint_delete (m_inner,
				     loc.m_inner);
}

inline void
diagnostic::take_execution_path (execution_path path)
{
  diagnostic_take_execution_path (m_inner,
				  path.m_inner);
  path.m_owned = false;
}

inline void
diagnostic::take_graph (graph g)
{
  diagnostic_take_graph (m_inner,
			 g.m_inner);
  g.m_owned = false;
}

inline void
diagnostic::finish (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  diagnostic_finish_va (m_inner, fmt, &ap);
  va_end (ap);
}

inline void
diagnostic::finish_va (const char *fmt, va_list *args)
{
  diagnostic_finish_va (m_inner, fmt, args);
}

inline void
diagnostic::finish_via_msg_buf (message_buffer &&msg_buf)
{
  diagnostic_message_buffer *inner_msg_buf = msg_buf.m_inner;
  msg_buf.m_inner = nullptr;
  diagnostic_finish_via_msg_buf (m_inner, inner_msg_buf);
}

// class manager

inline file
manager::new_file (const char *name,
		   const char *sarif_source_language)
{
  return file
    (diagnostic_manager_new_file (m_inner, name, sarif_source_language));
}

inline physical_location
manager::new_location_from_file_and_line (file f,
					  diagnostic_line_num_t line_num)
{
  return physical_location
    (diagnostic_manager_new_location_from_file_and_line (m_inner,
							 f.m_inner,
							 line_num));
}

inline physical_location
manager::new_location_from_file_line_column (file f,
					     line_num_t line_num,
					     column_num_t column_num)
{
  return physical_location
    (diagnostic_manager_new_location_from_file_line_column (m_inner,
							    f.m_inner,
							    line_num,
							    column_num));
}

inline physical_location
manager::new_location_from_range (physical_location loc_caret,
				  physical_location loc_start,
				  physical_location loc_end)
{
  return physical_location
    (diagnostic_manager_new_location_from_range (m_inner,
						 loc_caret.m_inner,
						 loc_start.m_inner,
						 loc_end.m_inner));
}

inline void
manager::debug_dump (physical_location loc,
		     FILE *out)
{
  diagnostic_manager_debug_dump_location (m_inner,
					  loc.m_inner,
					  out);
}
inline logical_location
manager::new_logical_location (enum diagnostic_logical_location_kind_t kind,
			       logical_location parent,
			       const char *short_name,
			       const char *fully_qualified_name,
			       const char *decorated_name)
{
  return logical_location
    (diagnostic_manager_new_logical_location (m_inner,
					      kind,
					      parent.m_inner,
					      short_name,
					      fully_qualified_name,
					      decorated_name));
}

inline void
manager::debug_dump (logical_location loc,
		     FILE *out)
{
  diagnostic_manager_debug_dump_logical_location (m_inner,
						  loc.m_inner,
						  out);
}

inline execution_path
manager::new_execution_path ()
{
  return execution_path (diagnostic_manager_new_execution_path (m_inner));
}

inline diagnostic
manager::begin_diagnostic (enum diagnostic_level level)
{
  return diagnostic (diagnostic_begin (m_inner, level));
}

inline void
manager::set_analysis_target (file f)
{
  diagnostic_manager_set_analysis_target (m_inner, f.m_inner);
}

inline void
manager::take_global_graph (graph g)
{
  diagnostic_manager_take_global_graph (m_inner,
					g.m_inner);
  g.m_owned = false;
}

// class graph

inline void
graph::set_description (const char *desc)
{
  diagnostic_graph_set_description (m_inner, desc);
}

inline void
graph::set_description (message_buffer &&msg_buf)
{
  diagnostic_message_buffer *inner_msg_buf = msg_buf.m_inner;
  msg_buf.m_inner = nullptr;
  diagnostic_graph_set_description_via_msg_buf (m_inner, inner_msg_buf);
}

inline node
graph::get_node_by_id (const char *id) const
{
  return node (diagnostic_graph_get_node_by_id (m_inner, id));
}

inline edge
graph::get_edge_by_id (const char *id) const
{
  return edge (diagnostic_graph_get_edge_by_id (m_inner, id));
}

inline edge
graph::add_edge (const char *id,
		 node src_node, node dst_node,
		 const char *label)
{
  return edge (diagnostic_graph_add_edge (m_inner,
					  id,
					  src_node.m_inner,
					  dst_node.m_inner,
					  label));
}

inline edge
graph::add_edge (const char *id,
		 node src_node, node dst_node,
		 message_buffer &&label)
{
  diagnostic_message_buffer *inner_label = label.m_inner;
  label.m_inner = nullptr;
  return edge (diagnostic_graph_add_edge_via_msg_buf (m_inner,
						      id,
						      src_node.m_inner,
						      dst_node.m_inner,
						      inner_label));
}

// class node

inline void
node::set_label (const char *label)
{
  diagnostic_node_set_label (m_inner, label);
}

inline void
node::set_label (message_buffer &&label)
{
  diagnostic_message_buffer *inner_label = label.m_inner;
  label.m_inner = nullptr;
  diagnostic_node_set_label_via_msg_buf (m_inner, inner_label);
}

inline void
node::set_location (physical_location loc)
{
  diagnostic_node_set_location (m_inner, loc.m_inner);
}

inline void
node::set_logical_location (logical_location loc)
{
  diagnostic_node_set_logical_location (m_inner, loc.m_inner);
}

} // namespace libgdiagnostics

#endif // #ifndef LIBGDIAGNOSTICSPP_H
