/* 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"


/**
 * 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;
  gboolean dirs_only;
  GList *basenames;

  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_free_full (completer->basenames, g_free);

  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_free_full (data->basenames, g_free);
  
  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_free_full (data->completer->basenames, g_free);
      
      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_free_full (data->completer->basenames, g_free);

      /* 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 zero-terminated=1) (transfer full): 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;
}
