/* -*- mode: C; c-file-style: "gnu" -*- */
/* xdgmimealias.c: Private file.  Datastructure for storing the hierarchy.
 *
 * More info can be found at http://www.freedesktop.org/standards/
 *
 * Copyright (C) 2004  Red Hat, Inc.
 * Copyright (C) 2004  Matthias Clasen <mclasen@redhat.com>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

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

#include "xdgmimeparent.h"
#include "xdgmimeint.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <fnmatch.h>

#ifndef	FALSE
#define	FALSE	(0)
#endif

#ifndef	TRUE
#define	TRUE	(!FALSE)
#endif

typedef struct XdgMimeParents XdgMimeParents;

struct XdgMimeParents
{
  char *mime;
  char **parents;
  int n_parents;
};

struct XdgParentList
{
  struct XdgMimeParents *parents;
  int n_mimes;
};

XdgParentList *
_xdg_mime_parent_list_new (void)
{
  XdgParentList *list;

  list = malloc (sizeof (XdgParentList));

  list->parents = NULL;
  list->n_mimes = 0;

  return list;
}

void         
_xdg_mime_parent_list_free (XdgParentList *list)
{
  int i;
  char **p;

  if (list->parents)
    {
      for (i = 0; i < list->n_mimes; i++)
	{
	  for (p = list->parents[i].parents; *p; p++)
	    free (*p);

	  free (list->parents[i].parents);
	  free (list->parents[i].mime);
	}
      free (list->parents);
    }
  free (list);
}

static int
parent_entry_cmp (const void *v1, const void *v2)
{
  return strcmp (((XdgMimeParents *)v1)->mime, ((XdgMimeParents *)v2)->mime);
}

const char **
_xdg_mime_parent_list_lookup (XdgParentList *list,
			      const char    *mime)
{
  XdgMimeParents *entry;
  XdgMimeParents key;

  if (list->n_mimes > 0)
    {
      key.mime = (char *)mime;
      key.parents = NULL;
      key.n_parents = 0;

      entry = bsearch (&key, list->parents, list->n_mimes,
		       sizeof (XdgMimeParents), &parent_entry_cmp);
      if (entry)
        return (const char **)entry->parents;
    }

  return NULL;
}

void
_xdg_mime_parent_read_from_file (XdgParentList *list,
				 const char    *file_name)
{
  FILE *file;
  char line[255];
  int i, alloc;
  XdgMimeParents *entry;

  file = fopen (file_name, "r");

  if (file == NULL)
    return;

  /* FIXME: Not UTF-8 safe.  Doesn't work if lines are greater than 255 chars.
   * Blah */
  alloc = list->n_mimes + 16;
  list->parents = realloc (list->parents, alloc * sizeof (XdgMimeParents));
  while (fgets (line, 255, file) != NULL)
    {
      char *sep;
      if (line[0] == '#')
	continue;

      sep = strchr (line, ' ');
      if (sep == NULL)
	continue;
      *(sep++) = '\000';
      sep[strlen (sep) -1] = '\000';
      entry = NULL;
      for (i = 0; i < list->n_mimes; i++)
	{
	  if (strcmp (list->parents[i].mime, line) == 0)
	    {
	      entry = &(list->parents[i]);
	      break;
	    }
	}
      
      if (!entry)
	{
	  if (list->n_mimes == alloc)
	    {
	      alloc <<= 1;
	      list->parents = realloc (list->parents, 
				       alloc * sizeof (XdgMimeParents));
	    }
	  list->parents[list->n_mimes].mime = strdup (line);
	  list->parents[list->n_mimes].parents = NULL;
	  entry = &(list->parents[list->n_mimes]);
	  list->n_mimes++;
	}

      if (!entry->parents)
	{
	  entry->n_parents = 1;
	  entry->parents = malloc ((entry->n_parents + 1) * sizeof (char *));
	}
      else
	{
	  entry->n_parents += 1;
	  entry->parents = realloc (entry->parents, 
				    (entry->n_parents + 2) * sizeof (char *));
	}
      entry->parents[entry->n_parents - 1] = strdup (sep);
      entry->parents[entry->n_parents] = NULL;
    }

  list->parents = realloc (list->parents, 
			   list->n_mimes * sizeof (XdgMimeParents));

  fclose (file);  
  
  if (list->n_mimes > 1)
    qsort (list->parents, list->n_mimes, 
           sizeof (XdgMimeParents), &parent_entry_cmp);
}

#ifdef NOT_USED_IN_GIO

void         
_xdg_mime_parent_list_dump (XdgParentList *list)
{
  int i;
  char **p;

  if (list->parents)
    {
      for (i = 0; i < list->n_mimes; i++)
	{
	  for (p = list->parents[i].parents; *p; p++)
	    printf ("%s %s\n", list->parents[i].mime, *p);
	}
    }
}

#endif

