/* debuginfod utilities for GDB.
   Copyright (C) 2020-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 <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 "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);
}

#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;
  gdb::optional<ui_out::progress_meter> meter;
};

/* 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>;

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);

  if (check_quit_flag ())
    {
      printf_filtered ("Cancelling download of %s %ps...\n",
		       data->desc,
		       styled_string (file_name_style.style (), data->fname));
      return 1;
    }

  if (total == 0)
    return 0;

  if (!data->meter.has_value ())
    {
      float size_in_mb = 1.0f * total / (1024 * 1024);
      string_file styled_filename (current_uiout->can_emit_style_escape ());
      fprintf_styled (&styled_filename,
		      file_name_style.style (),
		      "%s",
		      data->fname);
      std::string message
	= string_printf ("Downloading %.2f MB %s %s", size_in_mb, data->desc,
			 styled_filename.c_str());
      data->meter.emplace (current_uiout, message, 1);
    }

  current_uiout->progress ((double)cur / (double)total);

  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 = getenv (DEBUGINFOD_URLS_ENV_VAR);

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

  if (debuginfod_enabled == debuginfod_ask)
    {
      int resp = nquery (_("\nThis GDB supports auto-downloading debuginfo " \
			   "from the following URLs:\n%s\nEnable debuginfod " \
			   "for this session? "),
			 urls);
      if (!resp)
	{
	  printf_filtered (_("Debuginfod has been disabled.\nTo make this " \
			     "setting permanent, add \'set debuginfod " \
			     "enabled off\' to .gdbinit.\n"));
	  debuginfod_enabled = debuginfod_off;
	  return false;
	}

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

  return true;
}

/* 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);

  user_data data ("source file", srcpath);

  debuginfod_set_user_data (c, &data);
  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
  if (target_supports_terminal_ours ())
    {
      term_state.emplace ();
      target_terminal::ours ();
    }

  scoped_fd fd (debuginfod_find_source (c,
					build_id,
					build_id_len,
					srcpath,
					nullptr));
  debuginfod_set_user_data (c, nullptr);

  if (debuginfod_verbose > 0 && fd.get () < 0 && fd.get () != -ENOENT)
    printf_filtered (_("Download failed: %s.  Continuing without source file %ps.\n"),
		     safe_strerror (-fd.get ()),
		     styled_string (file_name_style.style (),  srcpath));

  if (fd.get () >= 0)
    *destname = make_unique_xstrdup (srcpath);

  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;
  user_data data ("separate debug info for", filename);

  debuginfod_set_user_data (c, &data);
  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
  if (target_supports_terminal_ours ())
    {
      term_state.emplace ();
      target_terminal::ours ();
    }

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

  if (debuginfod_verbose > 0 && fd.get () < 0 && fd.get () != -ENOENT)
    printf_filtered (_("Download failed: %s.  Continuing without debug info for %ps.\n"),
		     safe_strerror (-fd.get ()),
		     styled_string (file_name_style.style (),  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
  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)
{
  printf_unfiltered (_("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')
    fprintf_unfiltered (file, _("Debuginfod URLs have not been set.\n"));
  else
    fprintf_filtered (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)
{
  fprintf_filtered (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);
}
