/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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, 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, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>

#include "util.h"
#include "StringMap.h"
#include "LoadObject.h"
#include "DbeSession.h"
#include "DbeFile.h"
#include "SourceFile.h"
#include "Elf.h"
#include "gp-archive.h"
#include "ArchiveExp.h"
#include "Print.h"
#include "Module.h"

er_archive::er_archive (int argc, char *argv[]) : DbeApplication (argc, argv)
{
  force = 0;
  common_archive_dir = NULL;
  quiet = 0;
  descendant = 1;
  use_relative_path = 0;
  s_option = ARCH_EXE_ONLY;
  mask = NULL;
}

er_archive::~er_archive ()
{
  if (mask)
    {
      for (long i = 0, sz = mask->size (); i < sz; i++)
	{
	  regex_t *regex_desc = mask->get (i);
	  regfree (regex_desc);
	  delete regex_desc;
	}
      delete mask;
    }
  delete common_archive_dir;
}

int
er_archive::mask_is_on (const char *str)
{
  if (mask == NULL)
    return 1;
  for (long i = 0, sz = mask->size (); i < sz; i++)
    {
      regex_t *regex_desc = mask->get (i);
      if (regexec (regex_desc, str, 0, NULL, 0) == 0)
	return 1;
    }
  return 0;
}

void
er_archive::usage ()
{
/*
  fprintf (stderr, GTXT ("Usage: %s [-nqFV] [-a on|ldobjects|src|usedldobjects|usedsrc|off] [-m regexp] experiment\n"), whoami);
*/

/*
  Ruud - Isolate this line because it has an argument.  Otherwise it would be at the
  end of this long list.
*/
  printf ( GTXT (
    "Usage: gprofng archive [OPTION(S)] EXPERIMENT\n"));

  printf ( GTXT (
    "\n"
    "Archive the associated application binaries and source files in a gprofng\n"
    "experiment to make it self contained and portable.\n"
    "\n"
    "Options:\n"
    "\n"
    " --version           print the version number and exit.\n"
    " --help              print usage information and exit.\n"
    " --verbose {on|off}  enable (on) or disable (off) verbose mode; the default is \"off\".\n"
    "\n"
    " -a {off|on|ldobjects|src|usedldobjects|usedsrc}  specify archiving of binaries and other files;\n"
    "                    in addition to disable this feature (off), or enable archiving off all\n"
    "                    loadobjects and sources (on), the other options support a more\n"
    "                    refined selection. All of these options enable archiving, but the\n"
    "                    keyword controls what exactly is selected: all load objects (ldobjects),\n"
    "                    all source files (src), the loadobjects asscoiated with a program counter\n"
    "                    (usedldobjects), or the source files associated with a program counter\n"
    "                    (usedsrc); the default is \"-a ldobjects\".\n"
    "\n"
    " -n                 archive the named experiment only, not any of its descendants.\n"
    "\n"
    " -q                 do not write any warnings to stderr; messages are archived and\n"
    "                    can be retrieved later.\n"
    "\n"
    " -F                 force writing or rewriting of the archive; ignored with the -n\n"
    "                    or -m options, or if this is a subexperiment.\n"
    "\n"
    " -d <path>          specifies the location of a common archive; this is a directory that\n"
    "                    contains archived files.\n"
    "\n"
    " -m <regex>         archive only those source, object, and debug info files whose full\n"
    "                    path name matches the given POSIX compliant regular expression.\n"
    "\n"
    "Limitations:\n"
    "\n"
    "Default archiving does not occur in case the application profiled terminates prematurely,\n"
    "or if archiving is disabled when collecting the performance data. In such cases, this\n"
    "tool can be used to afterwards archive the information, but it has to run on the same \n"
    "system where the profiling data was recorded.\n"
    "\n"
    "Documentation:\n"
    "\n"
    "A getting started guide for gprofng is maintained as a Texinfo manual. If the info and\n"
    "gprofng programs are properly installed at your site, the command \"info gprofng\"\n"
    "should give you access to this document.\n"
    "\n"
    "See also:\n"
    "\n"
    "gprofng(1), gp-collect-app(1), gp-display-html(1), gp-display-src(1), gp-display-text(1)\n"));
// Ruud
/*
  fprintf (stderr, GTXT ("GNU %s version %s\n"), get_basename (prog_name), VERSION);
*/
  exit (1);
}

Vector <LoadObject*> *
er_archive::get_loadObjs ()
{
  Vector <LoadObject*> *objs = new Vector<LoadObject*>();
  Vector <LoadObject*> *loadObjs = dbeSession->get_text_segments ();
  if (s_option != ARCH_NOTHING)
    {
      for (long i = 0, sz = VecSize(loadObjs); i < sz; i++)
	{
	  LoadObject *lo = loadObjs->get (i);
	  if ((lo->flags & SEG_FLAG_DYNAMIC) != 0)
	    continue;
	  DbeFile *df = lo->dbeFile;
	  if (df && ((df->filetype & DbeFile::F_FICTION) != 0))
	    continue;
	  if (!lo->isUsed && ((s_option & (ARCH_USED_EXE_ONLY | ARCH_USED_SRC_ONLY)) != 0))
	    continue;
	  objs->append (lo);
	}
    }
  if (DEBUG_ARCHIVE)
    {
      Dprintf (DEBUG_ARCHIVE, NTXT ("get_text_segments(): %d\n"),
	       (int) (loadObjs ? loadObjs->size () : -1));
      for (long i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
	{
	  LoadObject *lo = loadObjs->get (i);
	  Dprintf (DEBUG_ARCHIVE, NTXT ("%s:%d  [%2ld] %s\n"),
		   get_basename (__FILE__), (int) __LINE__, i, STR (lo->dump ()));
	}
      Dprintf (DEBUG_ARCHIVE, NTXT ("\nget_loadObjs(): %d\n"),
	       (int) (objs ? objs->size () : -1));
      for (long i = 0, sz = VecSize(objs); i < sz; i++)
	{
	  LoadObject *lo = objs->get (i);
	  Dprintf (DEBUG_ARCHIVE, NTXT ("%s:%d  [%2ld] %s\n"),
		   get_basename (__FILE__), (int) __LINE__, i, STR (lo->dump ()));
	}
    }
  delete loadObjs;
  return objs;
}

/**
 * Clean old archive
 * Except the following cases:
 * 1. Founder experiment is an MPI experiment
 * 2. "-n" option is passed (do not archive descendants)
 * 3. "-m" option is passed (partial archiving)
 * 4. Experiment name is not the founder experiment (it is a sub-experiment)
 * @param expname
 * @param founder_exp
 * @return 0 - success
 */
int
er_archive::clean_old_archive (char *expname, ArchiveExp *founder_exp)
{
  if (0 == descendant)
    { // do not archive descendants
      fprintf (stderr, GTXT ("Warning: Option -F is ignored because -n option is specified (do not archive descendants)\n"));
      return 1;
    }
  if (NULL != mask)
    { // partial archiving
      fprintf (stderr, GTXT ("Warning: Option -F is ignored because -m option is specified\n"));
      return 1;
    }
  // Check if the experiment is the founder
  char *s1 = dbe_strdup (expname);
  char *s2 = dbe_strdup (founder_exp->get_expt_name ());
  if (!s1 || !s2)
    {
      fprintf (stderr, GTXT ("Cannot allocate memory\n"));
      exit (1);
    }
  // remove trailing slashes
  for (int n = strlen (s1); n > 0; n--)
    {
      if ('/' != s1[n - 1])
	break;
      s1[n - 1] = 0;
    }
  for (int n = strlen (s2); n > 0; n--)
    {
      if ('/' != s2[n - 1])
	break;
      s2[n - 1] = 0;
    }
  if (strcmp (s1, s2) != 0)
    { // not founder
      fprintf (stderr, GTXT ("Warning: Option -F is ignored because specified experiment name %s does not match founder experiment name %s\n"), s1, s2);
      free (s1);
      free (s2);
      return 1;
    }
  // Remove old "archives"
  char *arch = founder_exp->get_arch_name ();
  fprintf (stderr, GTXT ("INFO: removing existing archive: %s\n"), arch);
  if (dbe_stat (arch, NULL) == 0)
    {
      char *cmd = dbe_sprintf ("/bin/rm -rf %s", arch);
      system (cmd);
      free (cmd);
      if (dbe_stat (arch, NULL) != 0)
	{ // create "archives"
	  if (!founder_exp->create_dir (founder_exp->get_arch_name ()))
	    {
	      fprintf (stderr, GTXT ("Unable to create directory `%s'\n"), founder_exp->get_arch_name ());
	      exit (1);
	    }
	}
    }
  free (s1);
  free (s2);
  return 0;
} // clean_old_archive_if_necessary

void
er_archive::start (int argc, char *argv[])
{
  int last = argc - 1;
  if (check_args (argc, argv) != last)
    usage ();
  check_env_var ();
  if (s_option == ARCH_NOTHING)
    return;

  ArchiveExp *founder_exp = new ArchiveExp (argv[last]);
  if (founder_exp->get_status () == Experiment::FAILURE)
    {
      if (!quiet)
	fprintf (stderr, GTXT ("gp-archive: %s: %s\n"), argv[last],
		 pr_mesgs (founder_exp->fetch_errors (), NTXT (""), NTXT ("")));
      exit (1);
    }
  if (!founder_exp->create_dir (founder_exp->get_arch_name ()))
    {
      fprintf (stderr, GTXT ("Unable to create directory `%s'\n"), founder_exp->get_arch_name ());
      exit (1);
    }
  if (!common_archive_dir)
    common_archive_dir = dbe_strdup (getenv ("GPROFNG_ARCHIVE_COMMON_DIR"));
  if (common_archive_dir)
    {
      if (!founder_exp->create_dir (common_archive_dir))
	if (dbe_stat (common_archive_dir, NULL) != 0)
	  {
	    fprintf (stderr, GTXT ("Unable to create directory for common archive `%s'\n"), common_archive_dir);
	    exit (1);
	  }
    }
  // Clean old archives if necessary
  if (force)
    clean_old_archive (argv[last], founder_exp);
  Vector<ArchiveExp*> *exps = new Vector<ArchiveExp*>();
  exps->append (founder_exp);
  if (descendant)
    {
      Vector<char*> *exp_names = founder_exp->get_descendants_names ();
      if (exp_names)
	{
	  for (long i = 0, sz = exp_names->size (); i < sz; i++)
	    {
	      char *exp_path = exp_names->get (i);
	      ArchiveExp *exp = new ArchiveExp (exp_path);
	      if (exp->get_status () == Experiment::FAILURE)
		{
		  if (!quiet)
		    fprintf (stderr, GTXT ("gp-archive: %s: %s\n"), exp_path,
			     pr_mesgs (exp->fetch_errors (), "", ""));
		  delete exp;
		  continue;
		}
	      exps->append (exp);
	    }
	  exp_names->destroy ();
	  delete exp_names;
	}
    }
  for (long i = 0, sz = exps->size (); i < sz; i++)
    {
      ArchiveExp *exp = exps->get (i);
      exp->read_data (s_option);
    }

  Vector <DbeFile*> *copy_files = new Vector<DbeFile*>();
  Vector <LoadObject*> *loadObjs = get_loadObjs ();
  for (long i = 0, sz = VecSize(loadObjs); i < sz; i++)
    {
      LoadObject *lo = loadObjs->get (i);
      if (strcmp (lo->get_pathname (), "LinuxKernel") == 0)
	continue;
      DbeFile *df = lo->dbeFile;
      if ((df->filetype & DbeFile::F_FICTION) != 0)
	continue;
      if (df->get_location () == NULL)
	{
	  copy_files->append (df);
	  continue;
	}
      if ((df->filetype & DbeFile::F_JAVACLASS) != 0)
	{
	  if (df->container)
	    { // Found in .jar file
	      copy_files->append (df->container);
	    }
	  copy_files->append (df);
	  if ((s_option & ARCH_EXE_ONLY) != 0)
	    continue;
	}
      lo->sync_read_stabs ();
      Elf *elf = lo->get_elf ();
      if (elf && (lo->checksum != 0) && (lo->checksum != elf->elf_checksum ()))
	{
	  if (!quiet)
	    fprintf (stderr, GTXT ("gp-archive: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored\n"),
		       df->get_location ());
	  continue;
	}
      copy_files->append (df);
      if (elf)
	{
	  Elf *f = elf->find_ancillary_files (lo->get_pathname ());
	  if (f)
	    copy_files->append (f->dbeFile);
	  for (long i1 = 0, sz1 = VecSize(elf->ancillary_files); i1 < sz1; i1++)
	    {
	      Elf *ancElf = elf->ancillary_files->get (i1);
	      copy_files->append (ancElf->dbeFile);
	    }
	}
      Vector<Module*> *modules = lo->seg_modules;
      for (long i1 = 0, sz1 = VecSize(modules); i1 < sz1; i1++)
	{
	  Module *mod = modules->get (i1);
	  if ((mod->flags & MOD_FLAG_UNKNOWN) != 0)
	    continue;
	  else if ((s_option & (ARCH_USED_EXE_ONLY | ARCH_USED_SRC_ONLY)) != 0 &&
		   !mod->isUsed)
	    continue;
	  if ((s_option & ARCH_ALL) != 0)
	    mod->read_stabs (false); // Find all Sources
	  if (mod->dot_o_file && mod->dot_o_file->dbeFile)
	    copy_files->append (mod->dot_o_file->dbeFile);
	}
    }
  delete loadObjs;

  int bmask = DbeFile::F_LOADOBJ | DbeFile::F_JAVACLASS | DbeFile::F_JAR_FILE |
	  DbeFile::F_DOT_O | DbeFile::F_DEBUG_FILE;
  if ((s_option & (ARCH_USED_SRC_ONLY | ARCH_ALL)) != 0)
    {
      bmask |= DbeFile::F_JAVA_SOURCE | DbeFile::F_SOURCE;
      Vector<SourceFile*> *sources = dbeSession->get_sources ();
      for (long i = 0, sz = VecSize(sources); i < sz; i++)
	{
	  SourceFile *src = sources->get (i);
	  if ((src->flags & SOURCE_FLAG_UNKNOWN) != 0)
	    continue;
	  else if ((s_option & ARCH_USED_SRC_ONLY) != 0)
	    {
	      if ((src->dbeFile->filetype & DbeFile::F_JAVA_SOURCE) != 0 &&
		  !src->isUsed)
		continue;
	    }
	  if (src->dbeFile)
	    copy_files->append (src->dbeFile);
	}
    }

  Vector <DbeFile*> *notfound_files = new Vector<DbeFile*>();
  for (long i = 0, sz = VecSize(copy_files); i < sz; i++)
    {
      DbeFile *df = copy_files->get (i);
      char *fnm = df->get_location ();
      char *nm = df->get_name ();
      Dprintf (DEBUG_ARCHIVE,
	       "%s::%d copy_files[%ld] filetype=%4d inArchive=%d '%s' --> '%s'\n",
	       get_basename (__FILE__), (int) __LINE__, i,
	       df->filetype, df->inArchive ? 1 : 0, STR (nm), STR (fnm));
      Dprintf (DEBUG_ARCHIVE && df->container,
	       "    copy_files[%ld]: Found '%s' in '%s'\n",
	       i, STR (nm), STR (df->container->get_name ()));
      if (fnm == NULL)
	{
	  if (!quiet)
	    notfound_files->append (df);
	  continue;
	}
      else if (df->inArchive)
	{
	  Dprintf (DEBUG_ARCHIVE,
		   "  NOT COPIED: copy_files[%ld]: inArchive=1 '%s'\n",
		   i, STR (nm));
	  continue;
	}
      else if ((df->filetype & bmask) == 0)
	{
	  Dprintf (DEBUG_ARCHIVE,
		   "  NOT COPIED: copy_files[%ld]: container=%p filetype=%d bmask=%d '%s'\n",
		   i, df->container, df->filetype, bmask, STR (nm));
	  continue;
	}
      else if (df->container &&
	       (df->filetype & (DbeFile::F_JAVA_SOURCE | DbeFile::F_SOURCE)) == 0)
	{
	  Dprintf (DEBUG_ARCHIVE,
		   "  NOT COPIED: copy_files[%ld]: container=%p filetype=%d bmask=%d '%s'\n",
		   i, df->container, df->filetype, bmask, STR (nm));
	  continue;
	}
      else if (!mask_is_on (df->get_name ()))
	{
	  Dprintf (DEBUG_ARCHIVE,
		   "  NOT COPIED: copy_files[%ld]: mask is off for '%s'\n",
		   i, STR (nm));
	  continue;
	}
      char *anm = founder_exp->getNameInArchive (nm, false);
      if (force)
	unlink (anm);
      int res = founder_exp->copy_file (fnm, anm, quiet, common_archive_dir, use_relative_path);
      if (0 == res)  // file successfully archived
	df->inArchive = 1;
      delete anm;
    }
  delete copy_files;

  if (notfound_files->size () > 0)
    {
      for (long i = 0, sz = notfound_files->size (); i < sz; i++)
	{
	  DbeFile *df = notfound_files->get (i);
	  fprintf (stderr, GTXT ("gp-archive: Cannot find file: `%s'\n"), df->get_name ());
	}
      fprintf (stderr,
        GTXT ("\n If you know the correct location of the missing file(s)"
	      " you can help gp-archive to find them by manually editing"
	      " the .gprofng.rc file."
	      " See the gp-archive man page for more details.\n"));
    }
  delete notfound_files;
}

int
er_archive::check_args (int argc, char *argv[])
{
  int opt;
  int rseen = 0;
  int dseen = 0;
  // Parsing the command line
  opterr = 0;
  optind = 1;
  static struct option long_options[] = {
    {"help",    no_argument,        0, 'h'},
    {"version", no_argument,        0, 'V'},
    {"whoami",  required_argument,  0, 'w'},
    {"outfile", required_argument,  0, 'O'},
    {NULL, 0, 0, 0}
  };
  while (1)
    {
      int option_index = 0;
      opt = getopt_long (argc, argv, NTXT (":VFa:d:qnr:m:"),
			 long_options, &option_index);
      if (opt == EOF)
	break;
      switch (opt)
	{
	case 'F':
	  force = 1;
	  break;
	case 'd': // Common archive directory (absolute path)
	  if (rseen)
	    {
	      fprintf (stderr, GTXT ("Error: invalid combination of options: -r and -d are in conflict.\n"));
	      return -1;
	    }
	  if (dseen)
	    fprintf (stderr, GTXT ("Warning: option -d was specified several times. Last value is used.\n"));
	  free (common_archive_dir);
	  common_archive_dir = strdup (optarg);
	  dseen = 1;
	  break;
	case 'q':
	  quiet = 1;
	  break;
	case 'n':
	  descendant = 0;
	  break;
	case 'r': // Common archive directory (relative path)
	  if (dseen)
	    {
	      fprintf (stderr, GTXT ("Error: invalid combination of options: -d and -r are in conflict.\n"));
	      return -1;
	    }
	  if (rseen)
	    fprintf (stderr, GTXT ("Warning: option -r was specified several times. Last value is used.\n"));
	  free (common_archive_dir);
	  common_archive_dir = strdup (optarg);
	  use_relative_path = 1;
	  rseen = 1;
	  break;
	case 'a':
	  if (strcmp (optarg, "off") == 0)
	    s_option = ARCH_NOTHING;
	  else if (strcmp (optarg, "on") == 0 ||
		   strcmp (optarg, "ldobjects") == 0)
	    s_option = ARCH_EXE_ONLY;
	  else if (strcmp (optarg, "usedldobjects") == 0)
	    s_option = ARCH_USED_EXE_ONLY;
	  else if (strcmp (optarg, "usedsrc") == 0)
	    s_option = ARCH_USED_EXE_ONLY | ARCH_USED_SRC_ONLY;
	  else if (strcmp (optarg, "all") == 0 || strcmp (optarg, "src") == 0)
	    s_option = ARCH_ALL;
	  else
	    {
	      fprintf (stderr, GTXT ("Error: invalid option: `-%c %s'\n"),
		       optopt, optarg);
	      return -1;
	    }
	  break;
	case 'm':
	  {
	    regex_t *regex_desc = new regex_t ();
	    if (regcomp (regex_desc, optarg, REG_EXTENDED | REG_NOSUB | REG_NEWLINE))
	      {
		delete regex_desc;
		fprintf (stderr, GTXT ("Error: invalid option: `-%c %s'\n"),
			 optopt, optarg);
		return -1;
	      }
	    if (mask == NULL)
	      mask = new Vector<regex_t *>();
	    mask->append (regex_desc);
	    break;
	  }
	case 'O':
	  {
	    int fd = open (optarg, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	    if (fd == -1)
	      {
		fprintf (stderr, GTXT ("gp-archive: Can't open %s: %s\n"),
			 optarg, strerror (errno));
		break;
	      }
	    if (dup2 (fd, 2) == -1)
	      {
		close (fd);
		fprintf (stderr, GTXT ("gp-archive: Can't divert stderr: %s\n"),
			 strerror (errno));
		break;
	      }
	    if (dup2 (fd, 1) == -1)
	      {
		close (fd);
		fprintf (stderr, GTXT ("gp-archive: Can't divert stdout: %s\n"),
			 strerror (errno));
		break;
	      }
	    close (fd);
	    struct timeval tp;
	    gettimeofday (&tp, NULL);
	    fprintf (stderr, "### Start %s#", ctime (&tp.tv_sec));
	    for (int i = 0; i < argc; i++)
	      fprintf (stderr, " %s", argv[i]);
	    fprintf (stderr, "\n");
	    break;
	  }
	case 'V':
// Ruud
	  Application::print_version_info ();
/*
	  printf (GTXT ("GNU %s version %s\n"), get_basename (prog_name), VERSION);
*/
	  exit (0);
	case 'w':
	  whoami = optarg;
	  break;
	case 'h':
	  usage ();
	  exit (0);
	case ':': // -s -m without operand
	  fprintf (stderr, GTXT ("Option -%c requires an operand\n"), optopt);
	  return -1;
	case '?':
	default:
	  fprintf (stderr, GTXT ("Unrecognized option: -%c\n"), optopt);
	  return -1;
	}
    }
  return optind;
}

void
er_archive::check_env_var ()
{
  char *ename = NTXT ("GPROFNG_ARCHIVE");
  char *var = getenv (ename);
  if (var == NULL)
    return;
  var = dbe_strdup (var);
  Vector<char*> *opts = new Vector<char*>();
  opts->append (ename);
  for (char *s = var;;)
    {
      while (*s && isblank (*s))
	s++;
      if (*s == 0)
	break;
      opts->append (s);
      while (*s && !isblank (*s))
	s++;
      if (*s == 0)
	break;
      *s = 0;
      s++;
    }
  if (opts->size () > 0)
    {
      char **arr = (char **) malloc (sizeof (char *) *opts->size ());
      for (long i = 0; i < opts->size (); i++)
	arr[i] = opts->get (i);
      if (-1 == check_args (opts->size (), arr))
	fprintf (stderr, GTXT ("Error: Wrong SP_ER_ARCHIVE: '%s'\n"), var);
      free (arr);
    }
  delete opts;
  free (var);
}

static int
real_main (int argc, char *argv[])
{
  er_archive *archive = new er_archive (argc, argv);
  dbeSession->archive_mode = 1;
  archive->start (argc, argv);
  dbeSession->unlink_tmp_files ();
  return 0;
}

/**
 * Call catch_out_of_memory(int (*real_main)(int, char*[]), int argc, char *argv[]) which will call real_main()
 * @param argc
 * @param argv
 * @return
 */
int
main (int argc, char *argv[])
{
  return catch_out_of_memory (real_main, argc, argv);
}
