/* Copyright (C) 2021-2025 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <i18n.h>
#include <Elf.h>
#include <collctrl.h>
#include <StringBuilder.h>
#include "collect.h"
#include "libiberty.h"

/* get_count_data -- format exec of bit to do the real work */
void
collect::get_count_data ()
{
  char command[8192];
  char *s;
  struct stat statbuf;

  // reserve space for original args, plus 30 arguments to bit
  nargs = origargc + 30;
  char **narglist = (char **) xcalloc (nargs, sizeof (char *));
  arglist = narglist;

  // construct the command for bit
  snprintf (command, sizeof (command), NTXT ("%s"), run_dir);
  s = strstr_r (command, NTXT ("/bin"));
  if (s != NULL)
    {
      // build command line for launching it
      snprintf (s, sizeof (command) - (s - command), NTXT ("/lib/compilers/bit"));
      if (stat (command, &statbuf) == -1)
	{
	  // if bit command does not exist there
	  char *first_look = xstrdup (command);
	  snprintf (command, sizeof (command), NTXT ("%s"), run_dir);
	  s = strstr (command, NTXT ("/bin"));
	  snprintf (s, sizeof (command) - (s - command), NTXT ("/prod/bin/bit"));
	  if (stat (command, &statbuf) == -1)
	    {
	      // if bit command does not exist
	      dbe_write (2, GTXT ("bit is not installed as `%s' or `%s'\nNo experiment is possible\n"), first_look, command);
	      exit (2);
	    }
	  free (first_look);
	}
      *arglist++ = xstrdup (command);
    }
  else
    {
      dbe_write (2, GTXT ("collect can't find install bin directory\n"));
      exit (1);
    }

  // Tell it to collect data
  *arglist++ = NTXT ("collect");

  // add the flag for real-data vs. static data
  switch (cc->get_count ())
    {
    case -1:
      *arglist++ = NTXT ("-i");
      *arglist++ = NTXT ("static");
      *arglist++ = NTXT ("-M");
      break;
    case 1:
      *arglist++ = NTXT ("-M");
      *arglist++ = NTXT ("-u");
      break;
    default:
      abort ();
    }

  // tell bit to produce an experiment
  *arglist++ = NTXT ("-e");

  // now copy an edited list of collect options to the arglist
  char **oargv = origargv;

  // skip the "collect"
  oargv++;
  int argc = 1;
  while (argc != targ_index)
    {
      char *p = *oargv;
      switch (p[1])
	{
	  // pass these arguments along, with parameter
	case 'o':
	case 'd':
	case 'g':
	case 'A':
	case 'C':
	case 'O':
	case 'N':
	  *arglist++ = *oargv++;
	  *arglist++ = *oargv++;
	  argc = argc + 2;
	  break;
	case 'I':
	  *arglist++ = *oargv++; // set the -I flag
	  *arglist++ = *oargv; // and the directory name
	  *arglist++ = NTXT ("-d"); // and the -d flag
	  *arglist++ = *oargv++; // to the same directory name
	  argc = argc + 2;
	  break;
	case 'n':
	case 'v':
	  // pass these arguments along as is
	  *arglist++ = *oargv++;
	  argc = argc + 1;
	  break;
	case 'x':
	  // skip one argument
	  oargv++;
	  argc++;
	  break;
	case 'c':
	case 'L':
	case 'y':
	case 'l':
	case 'F':
	case 'j':
	case 'J':
	case 'p':
	case 's':
	case 'h':
	case 'S':
	case 'm':
	case 'M':
	case 'H':
	case 'r':
	case 'i':
	  // skip two arguments
	  oargv++;
	  oargv++;
	  argc = argc + 2;
	  break;
	case 'R':
	case 'Z':
	default:
	  // these should never get this far
	  dbe_write (2, GTXT ("unexpected argument %s\n"), p);
	  abort ();
	}
    }

  // now copy the target and its arguments
  if (access (prog_name, X_OK) != 0)    // not found
    *arglist++ = *oargv++;
  else
    {
      oargv++;
      *arglist++ = prog_name;
    }
  while (*oargv != NULL)
    *arglist++ = *oargv++;

  /* now we have the full argument list composed; if verbose, print it */
  if ((verbose == 1) || (disabled))
    {
      /* describe the experiment */
      char *ccret = cc->show (0);
      if (ccret != NULL)
	{
	  writeStr (2, ccret);
	  free (ccret);
	}
      ccret = cc->show_expt ();
      if (ccret != NULL)
	{
	  /* write this to stdout */
	  writeStr (1, ccret);
	  free (ccret);
	}
      /* print the arguments to bit */
      arglist = narglist;
      StringBuilder sb;
      sb.append (NTXT ("Exec argv[] = "));
      for (int ret = 0; ret < nargs; ret++)
	{
	  if (narglist[ret] == NULL)
	    break;
	  if (ret > 0)
	    sb.append (NTXT (" "));
	  sb.append (narglist[ret]);
	}
      sb.append (NTXT ("\n\n"));
      write (2, sb.toString (), sb.length ());
    }

  /* check for dry run */
  if (disabled)
    exit (0);

  /* ensure original outputs restored for target */
  reset_output ();

  /* now exec the bit to instrument and run the target ... */
  // (void) execve( *narglist, narglist, origenvp);
  (void) execvp (*narglist, narglist);

  /* exec failed; no experiment to delete */
  /* restore output for collector */
  set_output ();
  char *em = strerror (errno);
  if (em == NULL)
    dbe_write (2, GTXT ("execve of %s failed: errno = %d\n"), narglist[0], errno);
  else
    dbe_write (2, GTXT ("execve of %s failed: %s\n"), narglist[0], em);
  exit (1);
}
