/*
 *  Copyright 1994-2022 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou 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 lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib/gstdio.h>
#include "globals.h"
#include "sequences.h"

extern gchar *sequences_dir;

#ifdef __APPLE__
#define st_mtim st_mtimespec
#endif

void
Sequences_new(void)
{
  DIR *dir;
  struct dirent *entry;
  const gchar *blah = Sequences_get_dir();

  sequences = xcalloc(1, sizeof(Sequences_t));
  sequences->seqs = NULL;

  dir = opendir(blah);

  if (NULL == dir) {
#ifdef DEBUG
    printf("[!] No user sequences found: %s: %s\n", blah, strerror(errno));
#endif
  } else {
    if (NULL == getenv("LEBINIOU_NO_SEQUENCES")) {
      while (NULL != (entry = readdir(dir))) {
        if (!is_equal(entry->d_name, ".") && !is_equal(entry->d_name, "..")) {
          Sequence_t *s = NULL;

          s = Sequence_load(entry->d_name);

          if (NULL != s) {
            sequences->seqs = g_list_prepend(sequences->seqs, (gpointer)s);
          }
        }
      }
    }

    if (closedir(dir) == -1) {
      xperror("closedir");
    }
  }

  sequences->seqs = g_list_sort(sequences->seqs, Sequence_sort_func);
  sequences->size = g_list_length(sequences->seqs);
  sequences->shuffler = Shuffler_new(sequences->size);
  Shuffler_set_mode(sequences->shuffler, Context_get_shuffler_mode(BD_SEQUENCES));
  Shuffler_verbose(sequences->shuffler);
}


void
Sequences_delete(void)
{
  GList *tmp;

  if (NULL == sequences) {
    return;
  }

  tmp = sequences->seqs;

  while (NULL != tmp) {
    Sequence_t *killme = (Sequence_t *)tmp->data;

    Sequence_delete(killme);
    tmp = g_list_next(tmp);
  }

  g_list_free(sequences->seqs);
  Shuffler_delete(sequences->shuffler);
  xfree(sequences);
  g_free(sequences_dir);
}


void
Sequences_set_dir(gchar *dir)
{
  sequences_dir = dir;
}


GList *
Sequences_find_last_updated(GList *seqs)
{
  GList *last_updated = NULL;
  time_t most_recent = 0;

  // get list of sequences mtime
  const gchar *sequences_dir = Sequences_get_dir();

  for (GList *seq = g_list_first(seqs); NULL != seq; seq = g_list_next(seq)) {
    Sequence_t *s = (Sequence_t *)seq->data;
    gchar *filename = g_strdup_printf("%s/%s.json", sequences_dir, s->name);
    GStatBuf sbuf;

    if (!g_stat(filename, &sbuf)) {
      if ((sbuf.st_mode & S_IFMT) == S_IFREG) {
        if (sbuf.st_mtim.tv_sec > most_recent) {
          most_recent = sbuf.st_mtim.tv_sec;
          last_updated = seq;
        }
      }
    }
    g_free(filename);
  }

  return last_updated;
}
