/* 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 <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 strdup (_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':
// Ruud
	Application::print_version_info ();
/*
	printf (NTXT ("GNU %s version %s\n"), get_basename (prog_name), VERSION);
*/
	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;
}

// Ruud
void
Application::print_version_info ()
{
  printf ( GTXT (
    "GNU %s binutils version %s\n"
    "Copyright (C) 2024 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);
}
