/* debuginfod utilities for GDB.
   Copyright (C) 2020-2023 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 "diagnostics.h"
#include <errno.h>
#include "gdbsupport/scoped_fd.h"
#include "debuginfod-support.h"
#include "gdbsupport/gdb_optional.h"
#include "cli/cli-cmds.h"
#include "cli/cli-style.h"
#include "cli-out.h"
#include "target.h"

/* Set/show debuginfod commands.  */
static cmd_list_element *set_debuginfod_prefix_list;
static cmd_list_element *show_debuginfod_prefix_list;

static const char debuginfod_on[] = "on";
static const char debuginfod_off[] = "off";
static const char debuginfod_ask[] = "ask";

static const char *debuginfod_enabled_enum[] =
{
  debuginfod_on,
  debuginfod_off,
  debuginfod_ask,
  nullptr
};

static const char *debuginfod_enabled =
#if defined(HAVE_LIBDEBUGINFOD)
  debuginfod_ask;
#else
  debuginfod_off;
#endif

static unsigned int debuginfod_verbose = 1;

#ifndef HAVE_LIBDEBUGINFOD
scoped_fd
debuginfod_source_query (const unsigned char *build_id,
			 int build_id_len,
			 const char *srcpath,
			 gdb::unique_xmalloc_ptr<char> *destname)
{
  return scoped_fd (-ENOSYS);
}

scoped_fd
debuginfod_debuginfo_query (const unsigned char *build_id,
			    int build_id_len,
			    const char *filename,
			    gdb::unique_xmalloc_ptr<char> *destname)
{
  return scoped_fd (-ENOSYS);
}

scoped_fd
debuginfod_exec_query (const unsigned char *build_id,
		       int build_id_len,
		       const char *filename,
		       gdb::unique_xmalloc_ptr<char> *destname)
{
  return scoped_fd (-ENOSYS);
}

#define NO_IMPL _("Support for debuginfod is not compiled into GDB.")

#else
#include <elfutils/debuginfod.h>

struct user_data
{
  user_data (const char *desc, const char *fname)
    : desc (desc), fname (fname)
  { }

  const char * const desc;
  const char * const fname;
  ui_out::progress_update progress;
};

/* Deleter for a debuginfod_client.  */

struct debuginfod_client_deleter
{
  void operator() (debuginfod_client *c)
  {
    debuginfod_end (c);
  }
};

using debuginfod_client_up
  = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;


/* Convert SIZE into a unit suitable for use with progress updates.
   SIZE should in given in bytes and will be converted into KB, MB, GB
   or remain unchanged. UNIT will be set to "B", "KB", "MB" or "GB"
   accordingly.  */

static const char *
get_size_and_unit (double &size)
{
  if (size < 1024)
    /* If size is less than 1 KB then set unit to B.  */
    return "B";

  size /= 1024;
  if (size < 1024)
    /* If size is less than 1 MB then set unit to KB.  */
    return "K";

  size /= 1024;
  if (size < 1024)
    /* If size is less than 1 GB then set unit to MB.  */
    return "M";

  size /= 1024;
  return "G";
}

static int
progressfn (debuginfod_client *c, long cur, long total)
{
  user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
  gdb_assert (data != nullptr);

  string_file styled_fname (current_uiout->can_emit_style_escape ());
  fprintf_styled (&styled_fname, file_name_style.style (), "%s",
		  data->fname);

  if (check_quit_flag ())
    {
      gdb_printf ("Cancelling download of %s %s...\n",
		  data->desc, styled_fname.c_str ());
      return 1;
    }

  if (debuginfod_verbose == 0)
    return 0;

  /* Print progress update.  Include the transfer size if available.  */
  if (total > 0)
    {
      /* Transfer size is known.  */
      double howmuch = (double) cur / (double) total;

      if (howmuch >= 0.0 && howmuch <= 1.0)
	{
	  double d_total = (double) total;
	  const char *unit =  get_size_and_unit (d_total);
	  std::string msg = string_printf ("Downloading %0.2f %s %s %s",
					   d_total, unit, data->desc,
					   styled_fname.c_str ());
	  data->progress.update_progress (msg, unit, howmuch, d_total);
	  return 0;
	}
    }

  std::string msg = string_printf ("Downloading %s %s",
				   data->desc, styled_fname.c_str ());
  data->progress.update_progress (msg);
  return 0;
}

static debuginfod_client *
get_debuginfod_client ()
{
  static debuginfod_client_up global_client;

  if (global_client == nullptr)
    {
      global_client.reset (debuginfod_begin ());

      if (global_client != nullptr)
	debuginfod_set_progressfn (global_client.get (), progressfn);
    }

  return global_client.get ();
}

/* Check if debuginfod is enabled.  If configured to do so, ask the user
   whether to enable debuginfod.  */

static bool
debuginfod_is_enabled ()
{
  const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));

  if (debuginfod_enabled == debuginfod_off
      || urls == nullptr
      || *urls == '\0')
    return false;

  if (debuginfod_enabled == debuginfod_ask)
    {
      gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
		    "from the following URLs:\n"));

      gdb::string_view url_view (urls);
      while (true)
	{
	  size_t off = url_view.find_first_not_of (' ');
	  if (off == gdb::string_view::npos)
	    break;
	  url_view = url_view.substr (off);
	  /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
	     hppa seem convinced url_view might be of SIZE_MAX length.
	     And so complains because the length of an array can only
	     be PTRDIFF_MAX.  */
	  DIAGNOSTIC_PUSH
	  DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
	  off = url_view.find_first_of (' ');
	  DIAGNOSTIC_POP
	  gdb_printf
	    (_("  <%ps>\n"),
	     styled_string (file_name_style.style (),
			    gdb::to_string (url_view.substr (0,
							     off)).c_str ()));
	  if (off == gdb::string_view::npos)
	    break;
	  url_view = url_view.substr (off);
	}

      int resp = nquery (_("Enable debuginfod for this session? "));
      if (!resp)
	{
	  gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
			"setting permanent, add \'set debuginfod " \
			"enabled off\' to .gdbinit.\n"));
	  debuginfod_enabled = debuginfod_off;
	  return false;
	}

      gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
		    "setting permanent, add \'set debuginfod enabled " \
		    "on\' to .gdbinit.\n"));
      debuginfod_enabled = debuginfod_on;
    }

  return true;
}

/* Print the result of the most recent attempted download.  */

static void
print_outcome (int fd, const char *desc, const char *fname)
{
  if (fd < 0 && fd != -ENOENT)
    gdb_printf (_("Download failed: %s.  Continuing without %s %ps.\n"),
		safe_strerror (-fd),
		desc,
		styled_string (file_name_style.style (), fname));
}

/* See debuginfod-support.h  */

scoped_fd
debuginfod_source_query (const unsigned char *build_id,
			 int build_id_len,
			 const char *srcpath,
			 gdb::unique_xmalloc_ptr<char> *destname)
{
  if (!debuginfod_is_enabled ())
    return scoped_fd (-ENOSYS);

  debuginfod_client *c = get_debuginfod_client ();

  if (c == nullptr)
    return scoped_fd (-ENOMEM);

  char *dname = nullptr;
  scoped_fd fd;
  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;

  {
    user_data data ("source file", srcpath);

    debuginfod_set_user_data (c, &data);
    if (target_supports_terminal_ours ())
      {
	term_state.emplace ();
	target_terminal::ours ();
      }

    fd = scoped_fd (debuginfod_find_source (c,
					    build_id,
					    build_id_len,
					    srcpath,
					    &dname));
    debuginfod_set_user_data (c, nullptr);
  }

  print_outcome (fd.get (), "source file", srcpath);

  if (fd.get () >= 0)
    destname->reset (dname);

  return fd;
}

/* See debuginfod-support.h  */

scoped_fd
debuginfod_debuginfo_query (const unsigned char *build_id,
			    int build_id_len,
			    const char *filename,
			    gdb::unique_xmalloc_ptr<char> *destname)
{
  if (!debuginfod_is_enabled ())
    return scoped_fd (-ENOSYS);

  debuginfod_client *c = get_debuginfod_client ();

  if (c == nullptr)
    return scoped_fd (-ENOMEM);

  char *dname = nullptr;
  scoped_fd fd;
  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;

  {
    user_data data ("separate debug info for", filename);

    debuginfod_set_user_data (c, &data);
    if (target_supports_terminal_ours ())
      {
	term_state.emplace ();
	target_terminal::ours ();
      }

    fd = scoped_fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
					       &dname));
    debuginfod_set_user_data (c, nullptr);
  }

  print_outcome (fd.get (), "separate debug info for", filename);

  if (fd.get () >= 0)
    destname->reset (dname);

  return fd;
}

/* See debuginfod-support.h  */

scoped_fd
debuginfod_exec_query (const unsigned char *build_id,
		       int build_id_len,
		       const char *filename,
		       gdb::unique_xmalloc_ptr<char> *destname)
{
  if (!debuginfod_is_enabled ())
    return scoped_fd (-ENOSYS);

  debuginfod_client *c = get_debuginfod_client ();

  if (c == nullptr)
    return scoped_fd (-ENOMEM);

  char *dname = nullptr;
  scoped_fd fd;
  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;

  {
    user_data data ("executable for", filename);

    debuginfod_set_user_data (c, &data);
    if (target_supports_terminal_ours ())
      {
	term_state.emplace ();
	target_terminal::ours ();
      }

    fd = scoped_fd (debuginfod_find_executable (c, build_id, build_id_len,
						&dname));
    debuginfod_set_user_data (c, nullptr);
  }

  print_outcome (fd.get (), "executable for", filename);

  if (fd.get () >= 0)
    destname->reset (dname);

  return fd;
}
#endif

/* Set callback for "set debuginfod enabled".  */

static void
set_debuginfod_enabled (const char *value)
{
#if defined(HAVE_LIBDEBUGINFOD)
  debuginfod_enabled = value;
#else
  /* Disabling debuginfod when gdb is not built with it is a no-op.  */
  if (value != debuginfod_off)
    error (NO_IMPL);
#endif
}

/* Get callback for "set debuginfod enabled".  */

static const char *
get_debuginfod_enabled ()
{
  return debuginfod_enabled;
}

/* Show callback for "set debuginfod enabled".  */

static void
show_debuginfod_enabled (ui_file *file, int from_tty, cmd_list_element *cmd,
			 const char *value)
{
  gdb_printf (file,
	      _("Debuginfod functionality is currently set to "
		"\"%s\".\n"), debuginfod_enabled);
}

/* Set callback for "set debuginfod urls".  */

static void
set_debuginfod_urls (const std::string &urls)
{
#if defined(HAVE_LIBDEBUGINFOD)
  if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0)
    warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno));
#else
  error (NO_IMPL);
#endif
}

/* Get callback for "set debuginfod urls".  */

static const std::string&
get_debuginfod_urls ()
{
  static std::string urls;
#if defined(HAVE_LIBDEBUGINFOD)
  const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);

  if (envvar != nullptr)
    urls = envvar;
  else
    urls.clear ();
#endif

  return urls;
}

/* Show callback for "set debuginfod urls".  */

static void
show_debuginfod_urls (ui_file *file, int from_tty, cmd_list_element *cmd,
		      const char *value)
{
  if (value[0] == '\0')
    gdb_printf (file, _("Debuginfod URLs have not been set.\n"));
  else
    gdb_printf (file, _("Debuginfod URLs are currently set to:\n%s\n"),
		value);
}

/* Show callback for "set debuginfod verbose".  */

static void
show_debuginfod_verbose_command (ui_file *file, int from_tty,
				 cmd_list_element *cmd, const char *value)
{
  gdb_printf (file, _("Debuginfod verbose output is set to %s.\n"),
	      value);
}

/* Register debuginfod commands.  */

void _initialize_debuginfod ();
void
_initialize_debuginfod ()
{
  /* set/show debuginfod */
  add_setshow_prefix_cmd ("debuginfod", class_run,
			  _("Set debuginfod options."),
			  _("Show debuginfod options."),
			  &set_debuginfod_prefix_list,
			  &show_debuginfod_prefix_list,
			  &setlist, &showlist);

  add_setshow_enum_cmd ("enabled", class_run, debuginfod_enabled_enum,
			_("Set whether to use debuginfod."),
			_("Show whether to use debuginfod."),
			_("\
When on, enable the use of debuginfod to download missing debug info and\n\
source files."),
			set_debuginfod_enabled,
			get_debuginfod_enabled,
			show_debuginfod_enabled,
			&set_debuginfod_prefix_list,
			&show_debuginfod_prefix_list);

  /* set/show debuginfod urls */
  add_setshow_string_noescape_cmd ("urls", class_run, _("\
Set the list of debuginfod server URLs."), _("\
Show the list of debuginfod server URLs."), _("\
Manage the space-separated list of debuginfod server URLs that GDB will query \
when missing debuginfo, executables or source files.\nThe default value is \
copied from the DEBUGINFOD_URLS environment variable."),
				   set_debuginfod_urls,
				   get_debuginfod_urls,
				   show_debuginfod_urls,
				   &set_debuginfod_prefix_list,
				   &show_debuginfod_prefix_list);

  /* set/show debuginfod verbose */
  add_setshow_zuinteger_cmd ("verbose", class_support,
			     &debuginfod_verbose, _("\
Set verbosity of debuginfod output."), _("\
Show debuginfod debugging."), _("\
When set to a non-zero value, display verbose output for each debuginfod \
query.\nTo disable, set to zero.  Verbose output is displayed by default."),
			     nullptr,
			     show_debuginfod_verbose_command,
			     &set_debuginfod_prefix_list,
			     &show_debuginfod_prefix_list);
}
