#include "aos/logging/log_namer.h"

#include <dirent.h>
#include <mntent.h>
#include <unistd.h>

#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ostream>
#include <string>

#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"

#include "aos/configuration.h"
#include "aos/time/time.h"

#if defined(__clang)
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif

ABSL_FLAG(std::string, logging_folder,
#ifdef AOS_ARCHITECTURE_arm_frc
          "",
#else
          "./logs",
#endif
          "The folder to log to.  If empty, search for the /media/sd*1/ "
          "folder and place logs there.");

namespace aos::logging {
namespace {
void AllocateLogName(char **filename, const char *directory,
                     const char *basename) {
  int fileindex = 0;
  DIR *const d = opendir(directory);
  if (d == nullptr) {
    PLOG(FATAL) << "could not open directory" << directory;
  }
  int index = 0;
  while (true) {
    errno = 0;
    struct dirent *const dir = readdir(d);
    if (dir == nullptr) {
      if (errno == 0) {
        break;
      } else {
        PLOG(FATAL) << "readdir(" << d << ") failed";
      }
    } else {
      char previous_date[512];
      // Look for previous index and date
      const std::string format_string = std::string(basename) + "-%d_%s";
      if (sscanf(dir->d_name, format_string.c_str(), &index, &previous_date) ==
          2) {
        if (index >= fileindex) {
          fileindex = index + 1;
        }
      }
    }
  }
  closedir(d);

  char previous[512];
  ::std::string path = ::std::string(directory) + "/" + basename + "-current";
  ssize_t len = ::readlink(path.c_str(), previous, sizeof(previous));
  if (len != -1) {
    previous[len] = '\0';
  } else {
    previous[0] = '\0';
    LOG(INFO) << "Could not find " << path;
  }
  // Remove subsecond accuracy (after the ".").  We don't need it, and it makes
  // the string very long
  std::string time_short = aos::ToString(aos::realtime_clock::now());
  time_short = time_short.substr(0, time_short.find("."));

  if (asprintf(filename, "%s/%s-%03d_%s", directory, basename, fileindex,
               time_short.c_str()) == -1) {
    PLOG(FATAL) << "couldn't create final name";
  }
  // Fix basename formatting.
  LOG(INFO) << "Created log file (" << *filename << "). Previous file was ("
            << directory << "/" << previous << ").";
}

bool FoundThumbDrive(const char *path) {
  FILE *mnt_fp = setmntent("/etc/mtab", "r");
  if (mnt_fp == nullptr) {
    LOG(FATAL) << "Could not open /etc/mtab";
  }

  bool found = false;
  struct mntent mntbuf;
  char buf[256];
  while (!found) {
    struct mntent *mount_list = getmntent_r(mnt_fp, &mntbuf, buf, sizeof(buf));
    if (mount_list == nullptr) {
      break;
    }
    if (strcmp(mount_list->mnt_dir, path) == 0) {
      found = true;
    }
  }
  endmntent(mnt_fp);
  return found;
}

bool FindDevice(char *device, size_t device_size) {
  char test_device[10];
  for (char i = 'a'; i < 'z'; ++i) {
    snprintf(test_device, sizeof(test_device), "/dev/sd%c", i);
    VLOG(1) << "Trying to access" << test_device;
    if (access(test_device, F_OK) != -1) {
      snprintf(device, device_size, "sd%c", i);
      return true;
    }
  }
  return false;
}

}  // namespace

std::optional<std::string> MaybeGetLogName(const char *basename) {
  if (absl::GetFlag(FLAGS_logging_folder).empty()) {
    char folder[128];
    {
      char dev_name[8];
      if (!FindDevice(dev_name, sizeof(dev_name))) {
        LOG(INFO) << "Waiting for a device";
        return std::nullopt;
      }
      snprintf(folder, sizeof(folder), "/media/%s1", dev_name);
      if (!FoundThumbDrive(folder)) {
        LOG(INFO) << "Waiting for" << folder;
        return std::nullopt;
      }
      snprintf(folder, sizeof(folder), "/media/%s1/", dev_name);
    }

    if (access(folder, F_OK) == -1) {
      LOG(FATAL) << "folder '" << folder
                 << "' does not exist. please create it.";
    }

    absl::SetFlag(&FLAGS_logging_folder, folder);
  }
  const std::string folder = absl::GetFlag(FLAGS_logging_folder);
  if (access(folder.c_str(), R_OK | W_OK) == -1) {
    LOG(FATAL) << "folder '" << folder << "' does not exist. please create it.";
  }
  LOG(INFO) << "logging to folder '" << folder << "'";

  char *tmp;
  AllocateLogName(&tmp, folder.c_str(), basename);

  std::string log_base_name = tmp;
  std::string log_roborio_name = log_base_name + "/";
  free(tmp);

  char *tmp2;
  if (asprintf(&tmp2, "%s/%s-current", folder.c_str(), basename) == -1) {
    PLOG(WARNING) << "couldn't create current symlink name";
  } else {
    if (unlink(tmp2) == -1 && (errno != EROFS && errno != ENOENT)) {
      LOG(WARNING) << "unlink('" << tmp2 << "') failed";
    }
    if (symlink(log_roborio_name.c_str(), tmp2) == -1) {
      PLOG(WARNING) << "symlink('" << log_roborio_name.c_str() << "', '" << tmp2
                    << "') failed";
    }
    free(tmp2);
  }
  return log_base_name;
}

std::string GetLogName(const char *basename) {
  std::optional<std::string> log_base_name;

  while (true) {
    log_base_name = MaybeGetLogName(basename);

    if (log_base_name.has_value()) {
      break;
    }

    sleep(5);
  }

  return log_base_name.value();
}

}  // namespace aos::logging
