//========================================================================
//
// gfile-xpdf.cc
//
// Miscellaneous file and directory name manipulation.
//
// Copyright 1996-2003 Glyph & Cog, LLC
// Copyright 2025 Adam Sampson <ats@offog.org>
//
// This contains the functions that are in xpdf's gfile.cc but not in
// Poppler's.
//
//========================================================================

#include <limits.h>
#include <pwd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>

#include "gfile-xpdf.h"

// Some systems don't define this, so just make it something reasonably
// large.
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif

//------------------------------------------------------------------------

std::string xpdfGetHomeDir() {
  if (char *s = getenv("HOME")) {
    return s;
  } else {
    struct passwd *pw;
    if (char *s = getenv("USER"))
      pw = getpwnam(s);
    else
      pw = getpwuid(getuid());
    if (pw)
      return pw->pw_dir;
    else
      return ".";
  }
}

std::string xpdfDirName(const std::string& fileName) {
  auto pos = fileName.rfind("/");
  if (pos == std::string::npos) {
    return "";
  }
  return fileName.substr(0, pos);
}

bool xpdfIsAbsolutePath(const std::string& path) {
  return (!path.empty()) && path[0] == '/';
}

bool endsWithDotPDF(const std::string& path) {
  auto len = path.size();
  return len >= 4
         && path[len - 4] == '.'
         && (path[len - 3] == 'p' || path[len - 3] == 'P')
         && (path[len - 2] == 'd' || path[len - 2] == 'D')
         && (path[len - 1] == 'f' || path[len - 1] == 'F');
}

time_t xpdfGetModTime(const std::string& fileName) {
  struct stat statBuf;

  if (stat(fileName.c_str(), &statBuf)) {
    return 0;
  }
  return statBuf.st_mtime;
}

std::string xpdfMakePathAbsolute(std::string path) {
  if (!xpdfIsAbsolutePath(path.c_str())) {
    char buf[PATH_MAX+1];
    if (getcwd(buf, sizeof(buf))) {
      path.insert(0, "/");
      path.insert(0, buf);
    }
  }
  return path;
}
