/* -*- 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.1 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/>.
 */

#include "config.h"

#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
