#ifndef _FGSTRING_H
#include "fgstring.h"
#endif

#ifndef _FGFILELIST_H
#include "fgfilelist.h"
#endif

#ifndef _FGLOGGER_H
#include "fglogger.h"
#endif

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

#include <sys/utsname.h>

// Globals
#ifndef _FGGLOB_H
#include "fgglob.h"
#endif

#ifndef _FGEXC_H
#include "fgexc.h"
#endif

FGString FGGlob::gHostName;
bool FGGlob::gLogDisabled = false;
int FGGlob::gMaxThreads = 5;
bool FGGlob::gVerbose = false;

void
usage(void)
{
  fprintf(stderr, "This is ftpgrab v0.1.2\n");
  fprintf(stderr, "Usage:\n");
  fprintf(stderr, "ftpgrab [-n]\n");
  fprintf(stderr, "-h             : Display this message\n");
  fprintf(stderr, "-n             : Do not output information to a log file\n");
  fprintf(stderr, "-l <filename>  : Output log to <filename> rather than default location\n");
  fprintf(stderr, "-r <filename>  : Use <filename> as rcfile rather than default\n");
  fprintf(stderr, "-t <num>       : Use up to <num> concurrent threads (1<=num<=50)\n");
  fprintf(stderr, "-v             : Output progress to console\n");
  fflush(stderr);
  exit(1);
}

int
main(int argc, char* const argv[])
{
  // Parse command line options
  char option;
  FGString rcFileName("ftpgrabrc");

  while ((option = getopt(argc, argv, "hnvl:r:t:")) != EOF) {
    switch (option) {
    case '?':
    case ':':
    case 'h':
      usage();
      break;
    case 'n':
      FGGlob::gLogDisabled = true;
      break;
    case 'l':
      FGLogger::SetLogName(optarg);
      break;
    case 'r':
      rcFileName = optarg;
      break;
    case 't':
      {
        int threads = atoi(optarg);
        if (threads < 1 || threads > 50) {
          usage();
        }
        FGGlob::gMaxThreads = threads;
      }
      break;
    case 'v':
      FGGlob::gVerbose = true;
      break;
    }
  }

  {
    // Initialize signal handling
    struct sigaction pipeAction;
    // Safety
    memset(&pipeAction, '\0', sizeof(pipeAction));
    pipeAction.sa_handler = SIG_IGN;
    sigemptyset(&pipeAction.sa_mask);

    sigaction(SIGPIPE, &pipeAction, NULL);
  }

  {
    // Get the current hostname
    struct utsname machineDetails;
    uname(&machineDetails);

    FGGlob::gHostName = machineDetails.nodename;
  }

  try {
    (void) FGLogger::GetLogger();
  }
  catch (FGException& e) {
    fprintf(stderr, "Failed to initialize logger - bailing!\n");
    exit(1);
  }

  FGLogger& log = FGLogger::GetLogger();
  log.LogMsg("ftpgrab startup", FGLogger::kFGLLInfo);

  log.LogMsg("Attempting to parse config file", FGLogger::kFGLLVerbose);
  FGFileList list;
  try {
    list.LoadConfig(rcFileName);
  }
  catch (FGException& e) {
    log.LogException(e);
    log.LogMsg("Failed to parse config file - bailing", FGLogger::kFGLLErr);
    exit(1);
  }
  log.LogMsg("Sucessfully parsed config file", FGLogger::kFGLLVerbose);
  list.GetAllFiles();

  log.LogMsg("ftpgrab exiting", FGLogger::kFGLLInfo);

  exit(0);
}
