/* 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 <stdlib.h>
#include <strings.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>

#include "Application.h"
#include "Settings.h"
#include "i18n.h"
#include "util.h"

Application::ProgressFunc Application::progress_func = NULL;
Application *theApplication;

Application::Application (int argc, char *argv[], char *fdhome)
{
  theApplication = this;
  cur_dir = NULL;
  prog_version = dbe_strdup (VERSION);
  set_name (strchr (argv[0], '/') ? argv[0] : NULL);
  whoami = get_basename (get_name ());

  // set up a queue for comments
  commentq = new Emsgqueue (NTXT ("app_commentq"));

  // Locate where the binaries are installed
  set_run_dir (fdhome);

  // Initialize I18N
  init_locale (run_dir);

  // Initialize licensing data
  lic_found = 0;
  lic_err = NULL;

  // Initialize worker threads
  number_of_worker_threads = 1;
#if DEBUG
  char *use_worker_threads = getenv (NTXT ("SP_USE_WORKER_THREADS"));
  if ((NULL != use_worker_threads) && (0 == strcasecmp (use_worker_threads, NTXT ("no"))))
    {
      number_of_worker_threads = 0;
    }
#endif /* DEBUG */
  settings = new Settings (this);
}

Application::~Application ()
{
  delete commentq;
  delete settings;
  free (prog_version);
  free (cur_dir);
  free (prog_name);
  free (run_dir);
}

// Set the name of the application (for messages)
void
Application::set_name (const char *_name)
{
  prog_name = get_realpath (_name);
}

char *
Application::get_realpath (const char *_name)
{
  if (_name == NULL)
    _name = "/proc/self/exe";
  char *exe_name = realpath (_name, NULL);
  if (exe_name)
    return exe_name;
  if (strchr (_name, '/') == NULL)
    {
      char *path = getenv ("PATH");
      if (path)
	for (char *s = path;; s++)
	  if (*s == ':' || *s == 0)
	    {
	      if (path != s)
		{
		  char *nm = dbe_sprintf (NTXT ("%.*s/%s"), (int) (s - path),
				   path, _name);
		  exe_name = realpath (nm, NULL);
		  free (nm);
		  if (exe_name)
		    return exe_name;
		}
	      if (*s == 0)
		break;
	      path = s + 1;
	    }
    }
  return xstrdup (_name);
}

// Set the directory where all binaries are found
void
Application::set_run_dir (char *fdhome)
{
  run_dir_with_spaces = NULL;
  if (fdhome)
    {
      char *path = dbe_sprintf ("%s/bin", fdhome);
      struct stat sbuf;
      if (stat (path, &sbuf) != -1)
	run_dir = path;
      else
	{
	  free (path);
	  run_dir = dbe_strdup (fdhome);
	}
    }
  else
    {
      run_dir = realpath (prog_name, NULL);
      if (run_dir == NULL)
	{
	  fprintf (stderr, // I18N won't work here -- not catopen yet.
		   GTXT ("Can't find location of %s\n"), prog_name);
	  run_dir = dbe_strdup (get_cur_dir ());
	}
      else
	{
	  char *d = strrchr (run_dir, '/');
	  if (d)
	    *d = 0;
	  // Check if the installation path contains spaces
	  if (strchr (run_dir, ' ') != NULL)
	    {
	      // Create a symbolic link without spaces
	      const char *dir = NTXT ("/tmp/.gprofngLinks");
	      char *symbolic_link = dbe_create_symlink_to_path (run_dir, dir);
	      if (NULL != symbolic_link)
		{
		  // Save old path to avoid memory leak
		  run_dir_with_spaces = run_dir;
		  // Use the path through symbolic link
		  run_dir = symbolic_link;
		}
	    }
	}
    }
}

char *
Application::get_cur_dir ()
{
  if (cur_dir == NULL)
    {
      char cwd[MAXPATHLEN];
      if (getcwd (cwd, sizeof (cwd)) == NULL)
	{
	  perror (prog_name);
	  exit (1);
	}
      cur_dir = dbe_strdup (canonical_path (cwd));
    }
  return cur_dir;
}

/**
 * Get number of worker threads
 * This is used to decide if it is ok to use worker threads for stat()
 * and other actions that can hang for a long time
 * @return number_of_worker_threads
 */
int
Application::get_number_of_worker_threads ()
{
  return number_of_worker_threads;
}

int
Application::check_args (int argc, char *argv[])
{
  int opt;
  // Parsing the command line
  opterr = 0;
  while ((opt = getopt (argc, argv, "V")) != EOF)
    switch (opt)
      {
      case 'V':
	Application::print_version_info ();
	exit (0);
      default:
	usage ();
      }
  return optind;
}

Emsg *
Application::fetch_comments ()
{
  if (commentq == NULL)
    return NULL;
  return commentq->fetch ();
}

void
Application::queue_comment (Emsg *m)
{
  commentq->append (m);
}

void
Application::delete_comments ()
{
  if (commentq != NULL)
    {
      delete commentq;
      commentq = new Emsgqueue (NTXT ("app_commentq"));
    }
}

int
Application::set_progress (int percentage, const char *proc_str)
{
  if (progress_func != NULL)
    return progress_func (percentage, proc_str);
  return 0;
}

void
Application::print_version_info ()
{
  printf ( GTXT (
    "GNU %s binutils version %s\n"
    "Copyright (C) 2025 Free Software Foundation, Inc.\n"
    "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n"
    "This is free software: you are free to change and redistribute it.\n"
    "There is NO WARRANTY, to the extent permitted by law.\n"),
    get_basename (prog_name), VERSION);
}
