/* List of target connections for GDB.

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

#include "defs.h"
#include "target-connection.h"

#include <map>

#include "inferior.h"
#include "target.h"

/* A map between connection number and representative process_stratum
   target.  */
static std::map<int, process_stratum_target *> process_targets;

/* The highest connection number ever given to a target.  */
static int highest_target_connection_num;

/* See target-connection.h.  */

void
connection_list_add (process_stratum_target *t)
{
  if (t->connection_number == 0)
    {
      t->connection_number = ++highest_target_connection_num;
      process_targets[t->connection_number] = t;
    }
}

/* See target-connection.h.  */

void
connection_list_remove (process_stratum_target *t)
{
  process_targets.erase (t->connection_number);
  t->connection_number = 0;
}

/* See target-connection.h.  */

std::string
make_target_connection_string (process_stratum_target *t)
{
  if (t->connection_string () != NULL)
    return string_printf ("%s %s", t->shortname (),
			  t->connection_string ());
  else
    return t->shortname ();
}

/* Prints the list of target connections and their details on UIOUT.

   If REQUESTED_CONNECTIONS is not NULL, it's a list of GDB ids of the
   target connections that should be printed.  Otherwise, all target
   connections are printed.  */

static void
print_connection (struct ui_out *uiout, const char *requested_connections)
{
  int count = 0;
  size_t what_len = 0;

  /* Compute number of lines we will print.  */
  for (const auto &it : process_targets)
    {
      if (!number_is_in_list (requested_connections, it.first))
	continue;

      ++count;

      process_stratum_target *t = it.second;

      size_t l = strlen (t->shortname ());
      if (t->connection_string () != NULL)
	l += 1 + strlen (t->connection_string ());

      if (l > what_len)
	what_len = l;
    }

  if (count == 0)
    {
      uiout->message (_("No connections.\n"));
      return;
    }

  ui_out_emit_table table_emitter (uiout, 4, process_targets.size (),
				   "connections");

  uiout->table_header (1, ui_left, "current", "");
  uiout->table_header (4, ui_left, "number", "Num");
  /* The text in the "what" column may include spaces.  Add one extra
     space to visually separate the What and Description columns a
     little better.  Compare:
      "* 1    remote :9999 Remote serial target in gdb-specific protocol"
      "* 1    remote :9999  Remote serial target in gdb-specific protocol"
  */
  uiout->table_header (what_len + 1, ui_left, "what", "What");
  uiout->table_header (17, ui_left, "description", "Description");

  uiout->table_body ();

  for (const auto &it : process_targets)
    {
      process_stratum_target *t = it.second;

      if (!number_is_in_list (requested_connections, t->connection_number))
	continue;

      ui_out_emit_tuple tuple_emitter (uiout, NULL);

      if (current_inferior ()->process_target () == t)
	uiout->field_string ("current", "*");
      else
	uiout->field_skip ("current");

      uiout->field_signed ("number", t->connection_number);

      uiout->field_string ("what", make_target_connection_string (t));

      uiout->field_string ("description", t->longname ());

      uiout->text ("\n");
    }
}

/* The "info connections" command.  */

static void
info_connections_command (const char *args, int from_tty)
{
  print_connection (current_uiout, args);
}

void _initialize_target_connection ();

void
_initialize_target_connection ()
{
  add_info ("connections", info_connections_command,
	    _("\
Target connections in use.\n\
Shows the list of target connections currently in use."));
}
