/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * 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.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "gfilenamecompleter.h"
#include "gfileenumerator.h"
#include "gfileattribute.h"
#include "gfile.h"
#include "gfileinfo.h"
#include "gcancellable.h"
#include <string.h>
#include "glibintl.h"

#include "gioalias.h"

/**
 * SECTION:gfilenamecompleter
 * @short_description: Filename Completer
 * @include: gio/gio.h
 * 
 * Completes partial file and directory names given a partial string by
 * looking in the file system for clues. Can return a list of possible 
 * completion strings for widget implementations.
 * 
 **/

enum {
  GOT_COMPLETION_DATA,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

typedef struct {
  GFilenameCompleter *completer;
  GFileEnumerator *enumerator;
  GCancellable *cancellable;
  gboolean should_escape;
  GFile *dir;
  GList *basenames;
  gboolean dirs_only;
} LoadBasenamesData;

struct _GFilenameCompleter {
  GObject parent;

  GFile *basenames_dir;
  gboolean basenames_are_escaped;
  GList *basenames;
  gboolean dirs_only;

  LoadBasenamesData *basename_loader;
};

G_DEFINE_TYPE (GFilenameCompleter, g_filename_completer, G_TYPE_OBJECT);

static void cancel_load_basenames (GFilenameCompleter *completer);

static void
g_filename_completer_finalize (GObject *object)
{
  GFilenameCompleter *completer;

  completer = G_FILENAME_COMPLETER (object);

  cancel_load_basenames (completer);

  if (completer->basenames_dir)
    g_object_unref (completer->basenames_dir);

  g_list_foreach (completer->basenames, (GFunc)g_free, NULL);
  g_list_free (completer->basenames);

  G_OBJECT_CLASS (g_filename_completer_parent_class)->finalize (object);
}

static void
g_filename_completer_class_init (GFilenameCompleterClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  
  gobject_class->finalize = g_filename_completer_finalize;
  /**
   * GFilenameCompleter::got-completion-data:
   * 
   * Emitted when the file name completion information comes available.
   **/
  signals[GOT_COMPLETION_DATA] = g_signal_new (I_("got-completion-data"),
					  G_TYPE_FILENAME_COMPLETER,
					  G_SIGNAL_RUN_LAST,
					  G_STRUCT_OFFSET (GFilenameCompleterClass, got_completion_data),
					  NULL, NULL,
					  g_cclosure_marshal_VOID__VOID,
					  G_TYPE_NONE, 0);
}

static void
g_filename_completer_init (GFilenameCompleter *completer)
{
}

/**
 * g_filename_completer_new:
 * 
 * Creates a new filename completer.
 * 
 * Returns: a #GFilenameCompleter.
 **/
GFilenameCompleter *
g_filename_completer_new (void)
{
  return g_object_new (G_TYPE_FILENAME_COMPLETER, NULL);
}

static char *
longest_common_prefix (char *a, char *b)
{
  char *start;

  start = a;

  while (g_utf8_get_char (a) == g_utf8_get_char (b))
    {
      a = g_utf8_next_char (a);
      b = g_utf8_next_char (b);
    }

  return g_strndup (start, a - start);
}

static void
load_basenames_data_free (LoadBasenamesData *data)
{
  if (data->enumerator)
    g_object_unref (data->enumerator);
  
  g_object_unref (data->cancellable);
  g_object_unref (data->dir);
  
  g_list_foreach (data->basenames, (GFunc)g_free, NULL);
  g_list_free (data->basenames);
  
  g_free (data);
}

static void
got_more_files (GObject *source_object,
		GAsyncResult *res,
		gpointer user_data)
{
  LoadBasenamesData *data = user_data;
  GList *infos, *l;
  GFileInfo *info;
  const char *name;
  gboolean append_slash;
  char *t;
  char *basename;

  if (data->completer == NULL)
    {
      /* Was cancelled */
      load_basenames_data_free (data);
      return;
    }

  infos = g_file_enumerator_next_files_finish (data->enumerator, res, NULL);

  for (l = infos; l != NULL; l = l->next)
    {
      info = l->data;

      if (data->dirs_only &&
	  g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
	{
	  g_object_unref (info);
	  continue;
	}
      
      append_slash = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
      name = g_file_info_get_name (info);
      if (name == NULL)
	{
	  g_object_unref (info);
	  continue;
	}

      
      if (data->should_escape)
	basename = g_uri_escape_string (name,
					G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,
					TRUE);
      else
	/* If not should_escape, must be a local filename, convert to utf8 */
	basename = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
      
      if (basename)
	{
	  if (append_slash)
	    {
	      t = basename;
	      basename = g_strconcat (basename, "/", NULL);
	      g_free (t);
	    }
	  
	  data->basenames = g_list_prepend (data->basenames, basename);
	}
      
      g_object_unref (info);
    }
  
  g_list_free (infos);
  
  if (infos)
    {
      /* Not last, get more files */
      g_file_enumerator_next_files_async (data->enumerator,
					  100,
					  0,
					  data->cancellable,
					  got_more_files, data);
    }
  else
    {
      data->completer->basename_loader = NULL;
      
      if (data->completer->basenames_dir)
	g_object_unref (data->completer->basenames_dir);
      g_list_foreach (data->completer->basenames, (GFunc)g_free, NULL);
      g_list_free (data->completer->basenames);
      
      data->completer->basenames_dir = g_object_ref (data->dir);
      data->completer->basenames = data->basenames;
      data->completer->basenames_are_escaped = data->should_escape;
      data->basenames = NULL;
      
      g_file_enumerator_close_async (data->enumerator, 0, NULL, NULL, NULL);

      g_signal_emit (data->completer, signals[GOT_COMPLETION_DATA], 0);
      load_basenames_data_free (data);
    }
}


static void
got_enum (GObject *source_object,
	  GAsyncResult *res,
	  gpointer user_data)
{
  LoadBasenamesData *data = user_data;

  if (data->completer == NULL)
    {
      /* Was cancelled */
      load_basenames_data_free (data);
      return;
    }
  
  data->enumerator = g_file_enumerate_children_finish (G_FILE (source_object), res, NULL);
  
  if (data->enumerator == NULL)
    {
      data->completer->basename_loader = NULL;

      if (data->completer->basenames_dir)
	g_object_unref (data->completer->basenames_dir);
      g_list_foreach (data->completer->basenames, (GFunc)g_free, NULL);
      g_list_free (data->completer->basenames);

      /* Mark uptodate with no basenames */
      data->completer->basenames_dir = g_object_ref (data->dir);
      data->completer->basenames = NULL;
      data->completer->basenames_are_escaped = data->should_escape;
      
      load_basenames_data_free (data);
      return;
    }
  
  g_file_enumerator_next_files_async (data->enumerator,
				      100,
				      0,
				      data->cancellable,
				      got_more_files, data);
}

static void
schedule_load_basenames (GFilenameCompleter *completer,
			 GFile *dir,
			 gboolean should_escape)
{
  LoadBasenamesData *data;

  cancel_load_basenames (completer);

  data = g_new0 (LoadBasenamesData, 1);
  data->completer = completer;
  data->cancellable = g_cancellable_new ();
  data->dir = g_object_ref (dir);
  data->should_escape = should_escape;
  data->dirs_only = completer->dirs_only;

  completer->basename_loader = data;
  
  g_file_enumerate_children_async (dir,
				   G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
				   0, 0,
				   data->cancellable,
				   got_enum, data);
}

static void
cancel_load_basenames (GFilenameCompleter *completer)
{
  LoadBasenamesData *loader;
  
  if (completer->basename_loader)
    {
      loader = completer->basename_loader; 
      loader->completer = NULL;
      
      g_cancellable_cancel (loader->cancellable);
      
      completer->basename_loader = NULL;
    }
}


/* Returns a list of possible matches and the basename to use for it */
static GList *
init_completion (GFilenameCompleter *completer,
		 const char *initial_text,
		 char **basename_out)
{
  gboolean should_escape;
  GFile *file, *parent;
  char *basename;
  char *t;
  int len;

  *basename_out = NULL;
  
  should_escape = ! (g_path_is_absolute (initial_text) || *initial_text == '~');

  len = strlen (initial_text);
  
  if (len > 0 &&
      initial_text[len - 1] == '/')
    return NULL;
  
  file = g_file_parse_name (initial_text);
  parent = g_file_get_parent (file);
  if (parent == NULL)
    {
      g_object_unref (file);
      return NULL;
    }

  if (completer->basenames_dir == NULL ||
      completer->basenames_are_escaped != should_escape ||
      !g_file_equal (parent, completer->basenames_dir))
    {
      schedule_load_basenames (completer, parent, should_escape);
      g_object_unref (file);
      return NULL;
    }
  
  basename = g_file_get_basename (file);
  if (should_escape)
    {
      t = basename;
      basename = g_uri_escape_string (basename, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
      g_free (t);
    }
  else
    {
      t = basename;
      basename = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
      g_free (t);
      
      if (basename == NULL)
	return NULL;
    }

  *basename_out = basename;

  return completer->basenames;
}

/**
 * g_filename_completer_get_completion_suffix:
 * @completer: the filename completer.
 * @initial_text: text to be completed.
 *
 * Obtains a completion for @initial_text from @completer.
 *  
 * Returns: a completed string, or %NULL if no completion exists. 
 *     This string is not owned by GIO, so remember to g_free() it 
 *     when finished.
 **/
char *
g_filename_completer_get_completion_suffix (GFilenameCompleter *completer,
					    const char *initial_text)
{
  GList *possible_matches, *l;
  char *prefix;
  char *suffix;
  char *possible_match;
  char *lcp;

  g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL);
  g_return_val_if_fail (initial_text != NULL, NULL);

  possible_matches = init_completion (completer, initial_text, &prefix);

  suffix = NULL;
  
  for (l = possible_matches; l != NULL; l = l->next)
    {
      possible_match = l->data;
      
      if (g_str_has_prefix (possible_match, prefix))
	{
	  if (suffix == NULL)
	    suffix = g_strdup (possible_match + strlen (prefix));
	  else
	    {
	      lcp = longest_common_prefix (suffix,
					   possible_match + strlen (prefix));
	      g_free (suffix);
	      suffix = lcp;
	      
	      if (*suffix == 0)
		break;
	    }
	}
    }

  g_free (prefix);
  
  return suffix;
}

/**
 * g_filename_completer_get_completions:
 * @completer: the filename completer.
 * @initial_text: text to be completed.
 * 
 * Gets an array of completion strings for a given initial text.
 * 
 * Returns: array of strings with possible completions for @initial_text.
 * This array must be freed by g_strfreev() when finished. 
 **/
char **
g_filename_completer_get_completions (GFilenameCompleter *completer,
				      const char         *initial_text)
{
  GList *possible_matches, *l;
  char *prefix;
  char *possible_match;
  GPtrArray *res;

  g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL);
  g_return_val_if_fail (initial_text != NULL, NULL);

  possible_matches = init_completion (completer, initial_text, &prefix);

  res = g_ptr_array_new ();
  for (l = possible_matches; l != NULL; l = l->next)
    {
      possible_match = l->data;

      if (g_str_has_prefix (possible_match, prefix))
	g_ptr_array_add (res,
			 g_strconcat (initial_text, possible_match + strlen (prefix), NULL));
    }

  g_free (prefix);

  g_ptr_array_add (res, NULL);

  return (char**)g_ptr_array_free (res, FALSE);
}

/**
 * g_filename_completer_set_dirs_only:
 * @completer: the filename completer.
 * @dirs_only: a #gboolean.
 * 
 * If @dirs_only is %TRUE, @completer will only 
 * complete directory names, and not file names.
 **/
void
g_filename_completer_set_dirs_only (GFilenameCompleter *completer,
				    gboolean dirs_only)
{
  g_return_if_fail (G_IS_FILENAME_COMPLETER (completer));

  completer->dirs_only = dirs_only;
}

#define __G_FILENAME_COMPLETER_C__
#include "gioaliasdef.c"
