/* Copyright (C) 2021 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 "util.h"
#include "DbeSession.h"
#include "Experiment.h"
#include "DbeFile.h"
#include "ExpGroup.h"
#include "DbeJarFile.h"

DbeFile::DbeFile (const char *filename)
{
  filetype = 0;
  name = dbe_strdup (filename);
  name = canonical_path (name);
  orig_location = NULL;
  location = NULL;
  location_info = NULL;
  jarFile = NULL;
  container = NULL;
  need_refind = true;
  inArchive = false;
  sbuf.st_atim.tv_sec = 0;
  experiment = NULL;
}

DbeFile::~DbeFile ()
{
  free (name);
  free (location);
  free (orig_location);
  free (location_info);
}

void
DbeFile::set_need_refind (bool val)
{
  if (val != need_refind)
    {
      free (location_info);
      location_info = NULL;
      need_refind = val;
    }
}

void
DbeFile::set_location (const char *filename)
{
  free (location);
  location = NULL;
  if (filename)
    {
      if (strncmp (filename, NTXT ("./"), 2) == 0)
	filename += 2;
      location = canonical_path (dbe_strdup (filename));
    }
  free (location_info);
  location_info = NULL;
  set_need_refind (false);
}

char *
DbeFile::get_location_info ()
{
  if (location_info == NULL)
    {
      char *fnm = get_name ();
      char *loc = get_location ();
      Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location_info: %s %s\n"),
	       STR (fnm), STR (loc));
      if (loc == NULL)
	{
	  if (filetype & F_FICTION)
	    location_info = dbe_strdup (fnm);
	  else
	    location_info = dbe_sprintf (GTXT ("%s (not found)"),
					 get_relative_path (fnm));
	}
      else
	{
	  char *r_fnm = get_relative_path (fnm);
	  char *r_loc = get_relative_path (loc);
	  if (strcmp (r_fnm, r_loc) == 0)
	    location_info = dbe_strdup (r_fnm);
	  else
	    {
	      char *bname = get_basename (r_fnm);
	      if (strcmp (bname, r_loc) == 0)  // found in current directory
		location_info = dbe_strdup (bname);
	      else
		location_info = dbe_sprintf (GTXT ("%s (found as %s)"), bname, r_loc);
	    }
	}
    }
  return location_info;
}

char *
DbeFile::getResolvedPath ()
{
  if (get_location ())
    return location;
  return name;
}

DbeFile *
DbeFile::getJarDbeFile (char *fnm, int sym)
{
  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::getJarDbeFile: %s fnm='%s' sym=%d\n"),
	   STR (name), STR (fnm), sym);
  DbeFile *df = NULL;
  if (sym)
    {
      char *s = strchr (fnm, sym);
      if (s)
	{
	  s = dbe_strndup (fnm, s - fnm);
	  df = dbeSession->getDbeFile (s, F_JAR_FILE | F_FILE);
	  free (s);
	}
    }
  if (df == NULL)
    df = dbeSession->getDbeFile (fnm, F_JAR_FILE | F_FILE);
  if (df && (df->experiment == NULL))
    df->experiment = experiment;
  return df;
}

char *
DbeFile::get_location (bool find_needed)
{
  Dprintf (DEBUG_DBE_FILE, NTXT ("get_location 0x%x %s\n"), filetype, STR (name));
  if (!find_needed)
    return need_refind ? NULL : location;
  if (location || !need_refind)
    return location;
  set_need_refind (false);
  if ((filetype & F_FICTION) != 0)
    return NULL;
  if (filetype == F_DIR_OR_JAR)
    {
      find_in_archives (name);
      if (location)
	{
	  filetype |= F_JAR_FILE | F_FILE;
	  return location;
	}
      find_in_pathmap (name);
      if (location)
	return location;
      if (check_access (name) == F_DIRECTORY)
	{
	  filetype |= F_DIRECTORY;
	  set_location (name);
	  return location;
	}
    }

  if ((filetype & F_FILE) != 0)
    {
      if (experiment)
	{
	  char *fnm = experiment->checkFileInArchive (name, false);
	  if (fnm)
	    {
	      set_location (fnm);
	      inArchive = true;
	      sbuf.st_mtime = 0; // Don't check timestamps
	      free (fnm);
	      return location;
	    }
	  if ((filetype & F_JAVACLASS) != 0)
	    {
	      if (orig_location)
		{
		  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d name='%s' orig_location='%s'\n"),
			   (int) __LINE__, name, orig_location);
		  // Parse a fileName attribute. There are 4 possibilities:
		  //   file:<Class_Name>
		  //   file:<name_of_jar_or_zip_file>
		  //   jar:file:<name_of_jar_or_zip_file>!<Class_Name>
		  //   zip:<name_of_jar_or_zip_file>!<Class_Name>
		  DbeFile *jar_df = NULL;
		  if (strncmp (orig_location, NTXT ("zip:"), 4) == 0)
		    jar_df = getJarDbeFile (orig_location + 4, '!');
		  else if (strncmp (orig_location, NTXT ("jar:file:"), 9) == 0)
		    jar_df = getJarDbeFile (orig_location + 9, '!');
		  else if (strncmp (orig_location, NTXT ("file:"), 5) == 0
			   && isJarOrZip (orig_location + 5))
		    jar_df = getJarDbeFile (orig_location + 5, 0);
		  if (jar_df)
		    {
		      if (find_in_jar_file (name, jar_df->get_jar_file ()))
			{
			  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s' jar='%s'\n"),
				   (int) __LINE__, name, STR (location), STR (jar_df->get_location ()));
			  inArchive = jar_df->inArchive;
			  container = jar_df;
			  return location;
			}
		    }
		  if (strncmp (orig_location, NTXT ("file:"), 5) == 0
		      && !isJarOrZip (orig_location + 5))
		    {
		      DbeFile *df = new DbeFile (orig_location + 5);
		      df->filetype = DbeFile::F_FILE;
		      df->experiment = experiment;
		      fnm = df->get_location ();
		      if (fnm)
			{
			  set_location (fnm);
			  inArchive = df->inArchive;
			  sbuf.st_mtime = df->sbuf.st_mtime;
			  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' orig_location='%s' location='%s'\n"),
				   (int) __LINE__, name, orig_location, fnm);
			  delete df;
			  return location;
			}
		      delete df;
		    }
		}
	      fnm = dbe_sprintf (NTXT ("%s/%s/%s"), experiment->get_expt_name (), SP_DYNAMIC_CLASSES, name);
	      if (find_file (fnm))
		{
		  inArchive = true;
		  sbuf.st_mtime = 0; // Don't check timestamps
		  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s'\n"),
			   (int) __LINE__, name, fnm);
		  free (fnm);
		  return location;
		}
	      free (fnm);
	    }
	}
    }

  if (dbeSession->archive_mode)
    {
      find_file (name);
      if (location)
	return location;
    }

  bool inPathMap = find_in_pathmap (name);
  if (location)
    return location;
  find_in_setpath (name, dbeSession->get_search_path ());
  if (location)
    return location;
  if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
    {
      find_in_classpath (name, dbeSession->get_classpath ());
      if (location)
	return location;
    }
  if (!inPathMap)
    find_file (name);
  Dprintf (DEBUG_DBE_FILE && (location == NULL),
	   "DbeFile::get_location:%d NOT FOUND name='%s'\n", __LINE__, name);
  return location;
}

int
DbeFile::check_access (const char *filename)
{
  if (filename == NULL)
    return F_NOT_FOUND;
  int st = dbe_stat (filename, &sbuf);
  Dprintf (DEBUG_DBE_FILE, NTXT ("check_access: %d 0x%x %s\n"), st, filetype, filename);
  if (st == 0)
    {
      if (S_ISDIR (sbuf.st_mode))
	return F_DIRECTORY;
      else if (S_ISREG (sbuf.st_mode))
	return F_FILE;
      return F_UNKNOWN; // Symbolic link or unknown type of file
    }
  sbuf.st_atim.tv_sec = 0;
  sbuf.st_mtime = 0; // Don't check timestamps
  return F_NOT_FOUND; // File not found
}

bool
DbeFile::isJarOrZip (const char *fnm)
{
  size_t len = strlen (fnm) - 4;
  return len > 0 && (strcmp (fnm + len, NTXT (".jar")) == 0
		     || strcmp (fnm + len, NTXT (".zip")) == 0);
}

char *
DbeFile::find_file (const char *filename)
{
  switch (check_access (filename))
    {
    case F_DIRECTORY:
      if (filetype == F_DIR_OR_JAR)
	filetype |= F_DIRECTORY;
      if ((filetype & F_DIRECTORY) != 0)
	set_location (filename);
      break;
    case F_FILE:
      if (filetype == F_DIR_OR_JAR)
	{
	  filetype |= F_FILE;
	  if (isJarOrZip (filename))
	    filetype |= F_JAR_FILE;
	}
      if ((filetype & F_DIRECTORY) == 0)
	set_location (filename);
      break;
    }
  return location;
}

DbeJarFile *
DbeFile::get_jar_file ()
{
  if (jarFile == NULL)
    {
      char *fnm = get_location ();
      if (fnm)
	jarFile = dbeSession->get_JarFile (fnm);
    }
  return jarFile;
}

char *
DbeFile::find_package_name (const char *filename, const char *dirname)
{
  char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
  if (!find_in_pathmap (nm))
    find_file (nm);
  free (nm);
  return location;
}

char *
DbeFile::find_in_directory (const char *filename, const char *dirname)
{
  if (filename && dirname)
    {
      char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
      find_file (nm);
      free (nm);
    }
  return location;
}

char *
DbeFile::find_in_jar_file (const char *filename, DbeJarFile *jfile)
{
  // Read .jar or .zip
  if (jfile == NULL)
    return NULL;
  int entry = jfile->get_entry (filename);
  if (entry >= 0)
    {
      char *fnm = dbeSession->get_tmp_file_name (filename, true);
      long long fsize = jfile->copy (fnm, entry);
      if (fsize >= 0)
	{
	  dbeSession->tmp_files->append (fnm);
	  set_location (fnm);
	  sbuf.st_size = fsize;
	  sbuf.st_mtime = 0; // Don't check timestamps
	  fnm = NULL;
	}
      free (fnm);
    }
  return location;
}

bool
DbeFile::find_in_pathmap (char *filename)
{
  Vector<pathmap_t*> *pathmaps = dbeSession->get_pathmaps ();
  bool inPathMap = false;
  if (strncmp (filename, NTXT ("./"), 2) == 0)
    filename += 2;
  for (int i = 0, sz = pathmaps ? pathmaps->size () : 0; i < sz; i++)
    {
      pathmap_t *pmp = pathmaps->fetch (i);
      size_t len = strlen (pmp->old_prefix);
      if (strncmp (pmp->old_prefix, filename, len) == 0
	  && (filename[len] == '/' || filename[len] == '\0'))
	{
	  inPathMap = true;
	  if (find_in_directory (filename + len, pmp->new_prefix))
	    {
	      return inPathMap;
	    }
	}
    }
  return inPathMap;
}

void
DbeFile::find_in_archives (char *filename)
{
  for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
    {
      ExpGroup *gr = dbeSession->expGroups->fetch (i1);
      if (gr->founder)
	{
	  char *nm = gr->founder->checkFileInArchive (filename, false);
	  if (nm)
	    {
	      find_file (nm);
	      if (location)
		{
		  sbuf.st_mtime = 0; // Don't check timestamps
		  return;
		}
	    }
	}
    }
}

void
DbeFile::find_in_setpath (char *filename, Vector<char*> *searchPath)
{
  char *base = get_basename (filename);
  for (int i = 0, sz = searchPath ? searchPath->size () : 0; i < sz; i++)
    {
      char *spath = searchPath->fetch (i);
      // Check file in each experiment directory
      if (streq (spath, "$") || streq (spath, NTXT ("$expts")))
	{
	  // find only in founders and only LoadObj.
	  for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
	    {
	      ExpGroup *gr = dbeSession->expGroups->fetch (i1);
	      char *exp_name = gr->founder->get_expt_name ();
	      if (gr->founder)
		{
		  if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
		    {
		      // Find with the package name
		      if (find_in_directory (filename, exp_name))
			 return;
		    }
		  if (find_in_directory (base, exp_name))
		    return;
		}
	    }
	  continue;
	}
      DbeFile *df = dbeSession->getDbeFile (spath, DbeFile::F_DIR_OR_JAR);
      if (df->get_location () == NULL)
	continue;
      if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
	{
	  if ((df->filetype & F_JAR_FILE) != 0)
	    {
	      if (find_in_jar_file (filename, df->get_jar_file ()))
		{
		  container = df;
		  return;
		}
	      continue;
	    }
	  else if ((df->filetype & F_DIRECTORY) != 0)
	    // Find with the package name
	    if (find_package_name (filename, spath))
	      return;
	}
      if ((df->filetype & F_DIRECTORY) != 0)
	if (find_in_directory (base, df->get_location ()))
	  return;
    }
}

void
DbeFile::find_in_classpath (char *filename, Vector<DbeFile*> *classPath)
{
  for (int i = 0, sz = classPath ? classPath->size () : 0; i < sz; i++)
    {
      DbeFile *df = classPath->fetch (i);
      if (df->get_location () == NULL)
	continue;
      if ((df->filetype & F_JAR_FILE) != 0)
	{
	  if (find_in_jar_file (filename, df->get_jar_file ()))
	    {
	      container = df;
	      return;
	    }
	}
      else if ((df->filetype & F_DIRECTORY) != 0)
	// Find with the package name
	if (find_package_name (filename, df->get_name ()))
	  return;
    }
}

struct stat64 *
DbeFile::get_stat ()
{
  if (sbuf.st_atim.tv_sec == 0)
    {
      int st = check_access (get_location (false));
      if (st == F_NOT_FOUND)
	return NULL;
    }
  return &sbuf;
}

bool
DbeFile::compare (DbeFile *df)
{
  if (df == NULL)
    return false;
  struct stat64 *st1 = get_stat ();
  struct stat64 *st2 = df->get_stat ();
  if (st1 == NULL || st2 == NULL)
    return false;
  if (st1->st_size != st2->st_size)
    return false;
  if (st1->st_mtim.tv_sec != st2->st_mtim.tv_sec)
    return false;
  return true;
}
