/* -*- mode: C; c-file-style: "gnu" -*- */
/* xdgmime.c: XDG Mime Spec mime resolver.  Based on version 0.11 of the spec.
 *
 * More info can be found at http://www.freedesktop.org/standards/
 * 
 * Copyright (C) 2003,2004  Red Hat, Inc.
 * Copyright (C) 2003,2004  Jonathan Blandford <jrb@alum.mit.edu>
 *
 * Licensed under the Academic Free License version 2.0
 * Or under the following terms:
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "cmakeconfig.h"
#endif

#include "xdgmime.h"
#include "xdgmimeint.h"
#include "xdgmimeglob.h"
#include "xdgmimemagic.h"
#include "xdgmimealias.h"
#include "xdgmimeicon.h"
#include "xdgmimeparent.h"
#include "xdgmimecache.h"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>

typedef struct XdgDirTimeList XdgDirTimeList;
typedef struct XdgCallbackList XdgCallbackList;

static int need_reread = TRUE;
static time_t last_stat_time = 0;

static XdgGlobHash *global_hash = NULL;
static XdgMimeMagic *global_magic = NULL;
static XdgAliasList *alias_list = NULL;
static XdgParentList *parent_list = NULL;
static XdgDirTimeList *dir_time_list = NULL;
static XdgCallbackList *callback_list = NULL;
static XdgIconList *icon_list = NULL;
static XdgIconList *generic_icon_list = NULL;

XdgMimeCache **_caches = NULL;
static int n_caches = 0;

const char xdg_mime_type_unknown[] = "application/octet-stream";
const char xdg_mime_type_empty[] = "application/x-zerosize";
const char xdg_mime_type_textplain[] = "text/plain";


enum
{
  XDG_CHECKED_UNCHECKED,
  XDG_CHECKED_VALID,
  XDG_CHECKED_INVALID
};

struct XdgDirTimeList
{
  time_t mtime;
  char *directory_name;
  int checked;
  XdgDirTimeList *next;
};

struct XdgCallbackList
{
  XdgCallbackList *next;
  XdgCallbackList *prev;
  int              callback_id;
  XdgMimeCallback  callback;
  void            *data;
  XdgMimeDestroy   destroy;
};

/* Function called by xdg_run_command_on_dirs.  If it returns TRUE, further
 * directories aren't looked at */
typedef int (*XdgDirectoryFunc) (const char *directory,
				 void       *user_data);

static void
xdg_dir_time_list_add (char   *file_name, 
		       time_t  mtime)
{
  XdgDirTimeList *list;

  for (list = dir_time_list; list; list = list->next) 
    {
      if (strcmp (list->directory_name, file_name) == 0)
        {
          free (file_name);
          return;
        }
    }
  
  list = calloc (1, sizeof (XdgDirTimeList));
  list->checked = XDG_CHECKED_UNCHECKED;
  list->directory_name = file_name;
  list->mtime = mtime;
  list->next = dir_time_list;
  dir_time_list = list;
}
 
static void
xdg_dir_time_list_free (XdgDirTimeList *list)
{
  XdgDirTimeList *next;

  while (list)
    {
      next = list->next;
      free (list->directory_name);
      free (list);
      list = next;
    }
}

static int
xdg_mime_init_from_directory (const char *directory)
{
  char *file_name;
  struct stat st;

  assert (directory != NULL);

  file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache");
  if (stat (file_name, &st) == 0)
    {
      XdgMimeCache *cache = _xdg_mime_cache_new_from_file (file_name);

      if (cache != NULL)
	{
	  xdg_dir_time_list_add (file_name, st.st_mtime);

	  _caches = realloc (_caches, sizeof (XdgMimeCache *) * (n_caches + 2));
	  _caches[n_caches] = cache;
          _caches[n_caches + 1] = NULL;
	  n_caches++;

	  return FALSE;
	}
    }
  free (file_name);

  file_name = malloc (strlen (directory) + strlen ("/mime/globs2") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/globs2");
  if (stat (file_name, &st) == 0)
    {
      _xdg_mime_glob_read_from_file (global_hash, file_name, TRUE);
      xdg_dir_time_list_add (file_name, st.st_mtime);
    }
  else
    {
      free (file_name);
      file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
      strcpy (file_name, directory); strcat (file_name, "/mime/globs");
      if (stat (file_name, &st) == 0)
        {
          _xdg_mime_glob_read_from_file (global_hash, file_name, FALSE);
          xdg_dir_time_list_add (file_name, st.st_mtime);
        }
      else
        {
          free (file_name);
        }
    }

  file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/magic");
  if (stat (file_name, &st) == 0)
    {
      _xdg_mime_magic_read_from_file (global_magic, file_name);
      xdg_dir_time_list_add (file_name, st.st_mtime);
    }
  else
    {
      free (file_name);
    }

  file_name = malloc (strlen (directory) + strlen ("/mime/aliases") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/aliases");
  _xdg_mime_alias_read_from_file (alias_list, file_name);
  free (file_name);

  file_name = malloc (strlen (directory) + strlen ("/mime/subclasses") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/subclasses");
  _xdg_mime_parent_read_from_file (parent_list, file_name);
  free (file_name);

  file_name = malloc (strlen (directory) + strlen ("/mime/icons") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/icons");
  _xdg_mime_icon_read_from_file (icon_list, file_name);
  free (file_name);

  file_name = malloc (strlen (directory) + strlen ("/mime/generic-icons") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/generic-icons");
  _xdg_mime_icon_read_from_file (generic_icon_list, file_name);
  free (file_name);

  return FALSE; /* Keep processing */
}

/* Runs a command on all the directories in the search path */
static void
xdg_run_command_on_dirs (XdgDirectoryFunc  func,
			 void             *user_data)
{
  const char *xdg_data_home;
  const char *xdg_data_dirs;
  const char *ptr;

  xdg_data_home = getenv ("XDG_DATA_HOME");
  if (xdg_data_home)
    {
      if ((func) (xdg_data_home, user_data))
	return;
    }
  else
    {
      const char *home;

      home = getenv ("HOME");
      if (home != NULL)
	{
	  char *guessed_xdg_home;
	  int stop_processing;

	  guessed_xdg_home = malloc (strlen (home) + strlen ("/.local/share/") + 1);
	  strcpy (guessed_xdg_home, home);
	  strcat (guessed_xdg_home, "/.local/share/");
	  stop_processing = (func) (guessed_xdg_home, user_data);
	  free (guessed_xdg_home);

	  if (stop_processing)
	    return;
	}
    }

  xdg_data_dirs = getenv ("XDG_DATA_DIRS");
  if (xdg_data_dirs == NULL)
    xdg_data_dirs = "/usr/local/share/:/usr/share/";

  ptr = xdg_data_dirs;

  while (*ptr != '\000')
    {
      const char *end_ptr;
      char *dir;
      int len;
      int stop_processing;

      end_ptr = ptr;
      while (*end_ptr != ':' && *end_ptr != '\000')
	end_ptr ++;

      if (end_ptr == ptr)
	{
	  ptr++;
	  continue;
	}

      if (*end_ptr == ':')
	len = end_ptr - ptr;
      else
	len = end_ptr - ptr + 1;
      dir = malloc (len + 1);
      strncpy (dir, ptr, len);
      dir[len] = '\0';
      stop_processing = (func) (dir, user_data);
      free (dir);

      if (stop_processing)
	return;

      ptr = end_ptr;
    }
}

/* Checks file_path to make sure it has the same mtime as last time it was
 * checked.  If it has a different mtime, or if the file doesn't exist, it
 * returns FALSE.
 *
 * FIXME: This doesn't protect against permission changes.
 */
static int
xdg_check_file (const char *file_path,
                int        *exists)
{
  struct stat st;

  /* If the file exists */
  if (stat (file_path, &st) == 0)
    {
      XdgDirTimeList *list;

      if (exists)
        *exists = TRUE;

      for (list = dir_time_list; list; list = list->next)
	{
	  if (! strcmp (list->directory_name, file_path))
	    {
	      if (st.st_mtime == list->mtime)
		list->checked = XDG_CHECKED_VALID;
	      else 
		list->checked = XDG_CHECKED_INVALID;

	      return (list->checked != XDG_CHECKED_VALID);
	    }
	}
      return TRUE;
    }

  if (exists)
    *exists = FALSE;

  return FALSE;
}

static int
xdg_check_dir (const char *directory,
	       int        *invalid_dir_list)
{
  int invalid, exists;
  char *file_name;

  assert (directory != NULL);

  /* Check the mime.cache file */
  file_name = malloc (strlen (directory) + strlen ("/mime/mime.cache") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/mime.cache");
  invalid = xdg_check_file (file_name, &exists);
  free (file_name);
  if (invalid)
    {
      *invalid_dir_list = TRUE;
      return TRUE;
    }
  else if (exists)
    {
      return FALSE;
    }

  /* Check the globs file */
  file_name = malloc (strlen (directory) + strlen ("/mime/globs") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/globs");
  invalid = xdg_check_file (file_name, NULL);
  free (file_name);
  if (invalid)
    {
      *invalid_dir_list = TRUE;
      return TRUE;
    }

  /* Check the magic file */
  file_name = malloc (strlen (directory) + strlen ("/mime/magic") + 1);
  strcpy (file_name, directory); strcat (file_name, "/mime/magic");
  invalid = xdg_check_file (file_name, NULL);
  free (file_name);
  if (invalid)
    {
      *invalid_dir_list = TRUE;
      return TRUE;
    }

  return FALSE; /* Keep processing */
}

/* Walks through all the mime files stat()ing them to see if they've changed.
 * Returns TRUE if they have. */
static int
xdg_check_dirs (void)
{
  XdgDirTimeList *list;
  int invalid_dir_list = FALSE;

  for (list = dir_time_list; list; list = list->next)
    list->checked = XDG_CHECKED_UNCHECKED;

  xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_check_dir,
			   &invalid_dir_list);

  if (invalid_dir_list)
    return TRUE;

  for (list = dir_time_list; list; list = list->next)
    {
      if (list->checked != XDG_CHECKED_VALID)
	return TRUE;
    }

  return FALSE;
}

/* We want to avoid stat()ing on every single mime call, so we only look for
 * newer files every 5 seconds.  This will return TRUE if we need to reread the
 * mime data from disk.
 */
static int
xdg_check_time_and_dirs (void)
{
  struct timeval tv;
  time_t current_time;
  int retval = FALSE;

  gettimeofday (&tv, NULL);
  current_time = tv.tv_sec;

  if (current_time >= last_stat_time + 5)
    {
      retval = xdg_check_dirs ();
      last_stat_time = current_time;
    }

  return retval;
}

/* Called in every public function.  It reloads the hash function if need be.
 */
static void
xdg_mime_init (void)
{
  if (xdg_check_time_and_dirs ())
    {
      xdg_mime_shutdown ();
    }

  if (need_reread)
    {
      global_hash = _xdg_glob_hash_new ();
      global_magic = _xdg_mime_magic_new ();
      alias_list = _xdg_mime_alias_list_new ();
      parent_list = _xdg_mime_parent_list_new ();
      icon_list = _xdg_mime_icon_list_new ();
      generic_icon_list = _xdg_mime_icon_list_new ();

      xdg_run_command_on_dirs ((XdgDirectoryFunc) xdg_mime_init_from_directory,
			       NULL);

      need_reread = FALSE;
    }
}

const char *
xdg_mime_get_mime_type_for_data (const void *data,
				 size_t      len,
				 int        *result_prio)
{
  const char *mime_type;

  if (len == 0)
    {
      *result_prio = 100;
      return XDG_MIME_TYPE_EMPTY;
    }

  xdg_mime_init ();

  if (_caches)
    mime_type = _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio);
  else
    mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0);

  if (mime_type)
    return mime_type;

  return _xdg_binary_or_text_fallback(data, len);
}

const char *
xdg_mime_get_mime_type_for_file (const char  *file_name,
                                 struct stat *statbuf)
{
  const char *mime_type;
  /* currently, only a few globs occur twice, and none
   * more often, so 5 seems plenty.
   */
  const char *mime_types[5];
  FILE *file;
  unsigned char *data;
  int max_extent;
  int bytes_read;
  struct stat buf;
  const char *base_name;
  int n;

  if (file_name == NULL)
    return NULL;
  if (! _xdg_utf8_validate (file_name))
    return NULL;

  xdg_mime_init ();

  if (_caches)
    return _xdg_mime_cache_get_mime_type_for_file (file_name, statbuf);

  base_name = _xdg_get_base_name (file_name);
  n = _xdg_glob_hash_lookup_file_name (global_hash, base_name, mime_types, 5);

  if (n == 1)
    return mime_types[0];

  if (!statbuf)
    {
      if (stat (file_name, &buf) != 0)
	return XDG_MIME_TYPE_UNKNOWN;

      statbuf = &buf;
    }

  if (!S_ISREG (statbuf->st_mode))
    return XDG_MIME_TYPE_UNKNOWN;

  /* FIXME: Need to make sure that max_extent isn't totally broken.  This could
   * be large and need getting from a stream instead of just reading it all
   * in. */
  max_extent = _xdg_mime_magic_get_buffer_extents (global_magic);
  data = malloc (max_extent);
  if (data == NULL)
    return XDG_MIME_TYPE_UNKNOWN;
        
  file = fopen (file_name, "r");
  if (file == NULL)
    {
      free (data);
      return XDG_MIME_TYPE_UNKNOWN;
    }

  bytes_read = fread (data, 1, max_extent, file);
  if (ferror (file))
    {
      free (data);
      fclose (file);
      return XDG_MIME_TYPE_UNKNOWN;
    }

  mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL,
					   mime_types, n);

  if (!mime_type)
    mime_type = _xdg_binary_or_text_fallback (data, bytes_read);

  free (data);
  fclose (file);

  return mime_type;
}

const char *
xdg_mime_get_mime_type_from_file_name (const char *file_name)
{
  const char *mime_type;

  xdg_mime_init ();

  if (_caches)
    return _xdg_mime_cache_get_mime_type_from_file_name (file_name);

  if (_xdg_glob_hash_lookup_file_name (global_hash, file_name, &mime_type, 1))
    return mime_type;
  else
    return XDG_MIME_TYPE_UNKNOWN;
}

int
xdg_mime_get_mime_types_from_file_name (const char *file_name,
					const char  *mime_types[],
					int          n_mime_types)
{
  xdg_mime_init ();
  
  if (_caches)
    return _xdg_mime_cache_get_mime_types_from_file_name (file_name, mime_types, n_mime_types);
  
  return _xdg_glob_hash_lookup_file_name (global_hash, file_name, mime_types, n_mime_types);
}

int
xdg_mime_is_valid_mime_type (const char *mime_type)
{
  /* FIXME: We should make this a better test
   */
  return _xdg_utf8_validate (mime_type);
}

void
xdg_mime_shutdown (void)
{
  XdgCallbackList *list;

  /* FIXME: Need to make this (and the whole library) thread safe */
  if (dir_time_list)
    {
      xdg_dir_time_list_free (dir_time_list);
      dir_time_list = NULL;
    }
	
  if (global_hash)
    {
      _xdg_glob_hash_free (global_hash);
      global_hash = NULL;
    }
  if (global_magic)
    {
      _xdg_mime_magic_free (global_magic);
      global_magic = NULL;
    }

  if (alias_list)
    {
      _xdg_mime_alias_list_free (alias_list);
      alias_list = NULL;
    }

  if (parent_list)
    {
      _xdg_mime_parent_list_free (parent_list);
      parent_list = NULL;
    }

  if (icon_list)
    {
      _xdg_mime_icon_list_free (icon_list);
      icon_list = NULL;
    }

  if (generic_icon_list)
    {
      _xdg_mime_icon_list_free (generic_icon_list);
      generic_icon_list = NULL;
    }
  
  if (_caches)
    {
      int i;

      for (i = 0; i < n_caches; i++)
        _xdg_mime_cache_unref (_caches[i]);
      free (_caches);
      _caches = NULL;
      n_caches = 0;
    }

  for (list = callback_list; list; list = list->next)
    (list->callback) (list->data);

  need_reread = TRUE;
}

int
xdg_mime_get_max_buffer_extents (void)
{
  xdg_mime_init ();
  
  if (_caches)
    return _xdg_mime_cache_get_max_buffer_extents ();

  return _xdg_mime_magic_get_buffer_extents (global_magic);
}

const char *
_xdg_mime_unalias_mime_type (const char *mime_type)
{
  const char *lookup;

  if (_caches)
    return _xdg_mime_cache_unalias_mime_type (mime_type);

  if ((lookup = _xdg_mime_alias_list_lookup (alias_list, mime_type)) != NULL)
    return lookup;

  return mime_type;
}

const char *
xdg_mime_unalias_mime_type (const char *mime_type)
{
  xdg_mime_init ();

  return _xdg_mime_unalias_mime_type (mime_type);
}

int
_xdg_mime_mime_type_equal (const char *mime_a,
			   const char *mime_b)
{
  const char *unalias_a, *unalias_b;

  unalias_a = _xdg_mime_unalias_mime_type (mime_a);
  unalias_b = _xdg_mime_unalias_mime_type (mime_b);

  if (strcmp (unalias_a, unalias_b) == 0)
    return 1;

  return 0;
}

int
xdg_mime_mime_type_equal (const char *mime_a,
			  const char *mime_b)
{
  xdg_mime_init ();

  return _xdg_mime_mime_type_equal (mime_a, mime_b);
}

int
xdg_mime_media_type_equal (const char *mime_a,
			   const char *mime_b)
{
  char *sep;

  sep = strchr (mime_a, '/');
  
  if (sep && strncmp (mime_a, mime_b, sep - mime_a + 1) == 0)
    return 1;

  return 0;
}

#if 1
static int
ends_with (const char *str,
           const char *suffix)
{
  int length;
  int suffix_length;

  length = strlen (str);
  suffix_length = strlen (suffix);
  if (length < suffix_length)
    return 0;

  if (strcmp (str + length - suffix_length, suffix) == 0)
    return 1;

  return 0;
}

static int
xdg_mime_is_super_type (const char *mime)
{
  return ends_with (mime, "/*");
}
#endif

int
_xdg_mime_mime_type_subclass (const char *mime,
			      const char *base)
{
  const char *umime, *ubase;
  const char **parents;

  if (_caches)
    return _xdg_mime_cache_mime_type_subclass (mime, base);

  umime = _xdg_mime_unalias_mime_type (mime);
  ubase = _xdg_mime_unalias_mime_type (base);

  if (strcmp (umime, ubase) == 0)
    return 1;

#if 1  
  /* Handle supertypes */
  if (xdg_mime_is_super_type (ubase) &&
      xdg_mime_media_type_equal (umime, ubase))
    return 1;
#endif

  /*  Handle special cases text/plain and application/octet-stream */
  if (strcmp (ubase, "text/plain") == 0 && 
      strncmp (umime, "text/", 5) == 0)
    return 1;

  if (strcmp (ubase, "application/octet-stream") == 0 &&
      strncmp (umime, "inode/", 6) != 0)
    return 1;
  
  parents = _xdg_mime_parent_list_lookup (parent_list, umime);
  for (; parents && *parents; parents++)
    {
      if (_xdg_mime_mime_type_subclass (*parents, ubase))
	return 1;
    }

  return 0;
}

int
xdg_mime_mime_type_subclass (const char *mime,
			     const char *base)
{
  xdg_mime_init ();

  return _xdg_mime_mime_type_subclass (mime, base);
}

char **
xdg_mime_list_mime_parents (const char *mime)
{
  const char **parents;
  char **result;
  int i, n;

  if (_caches)
    return _xdg_mime_cache_list_mime_parents (mime);

  parents = xdg_mime_get_mime_parents (mime);

  if (!parents)
    return NULL;

  for (i = 0; parents[i]; i++) ;
  
  n = (i + 1) * sizeof (char *);
  result = (char **) malloc (n);
  memcpy (result, parents, n);

  return result;
}

const char **
xdg_mime_get_mime_parents (const char *mime)
{
  const char *umime;

  xdg_mime_init ();

  umime = _xdg_mime_unalias_mime_type (mime);

  return _xdg_mime_parent_list_lookup (parent_list, umime);
}

void 
xdg_mime_dump (void)
{
  xdg_mime_init();

  printf ("*** ALIASES ***\n\n");
  _xdg_mime_alias_list_dump (alias_list);
  printf ("\n*** PARENTS ***\n\n");
  _xdg_mime_parent_list_dump (parent_list);
  printf ("\n*** CACHE ***\n\n");
  _xdg_glob_hash_dump (global_hash);
  printf ("\n*** GLOBS ***\n\n");
  _xdg_glob_hash_dump (global_hash);
  printf ("\n*** GLOBS REVERSE TREE ***\n\n");
  _xdg_mime_cache_glob_dump ();
}


/* Registers a function to be called every time the mime database reloads its files
 */
int
xdg_mime_register_reload_callback (XdgMimeCallback  callback,
				   void            *data,
				   XdgMimeDestroy   destroy)
{
  XdgCallbackList *list_el;
  static int callback_id = 1;

  /* Make a new list element */
  list_el = calloc (1, sizeof (XdgCallbackList));
  list_el->callback_id = callback_id;
  list_el->callback = callback;
  list_el->data = data;
  list_el->destroy = destroy;
  list_el->next = callback_list;
  if (list_el->next)
    list_el->next->prev = list_el;

  callback_list = list_el;
  callback_id ++;

  return callback_id - 1;
}

void
xdg_mime_remove_callback (int callback_id)
{
  XdgCallbackList *list;

  for (list = callback_list; list; list = list->next)
    {
      if (list->callback_id == callback_id)
	{
	  if (list->next)
	    list->next = list->prev;

	  if (list->prev)
	    list->prev->next = list->next;
	  else
	    callback_list = list->next;

	  /* invoke the destroy handler */
	  (list->destroy) (list->data);
	  free (list);
	  return;
	}
    }
}

const char *
xdg_mime_get_icon (const char *mime)
{
  xdg_mime_init ();
  
  if (_caches)
    return _xdg_mime_cache_get_icon (mime);

  return _xdg_mime_icon_list_lookup (icon_list, mime);
}

const char *
xdg_mime_get_generic_icon (const char *mime)
{
  xdg_mime_init ();
  
  if (_caches)
    return _xdg_mime_cache_get_generic_icon (mime);

  return _xdg_mime_icon_list_lookup (generic_icon_list, mime);
}

int
xdg_mime_get_simple_globs (const char *mime,
                           char       *globs[],
                           int         n_globs)
{
  xdg_mime_init ();

  if (_caches)
    return _xdg_mime_cache_get_simple_globs (mime, globs, n_globs);

  return _xdg_glob_hash_get_simple_globs (global_hash, mime, globs, n_globs);
}
