/* 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.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/>.
 *
 * 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,
					  NULL,
					  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 up-to-date 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: (nullable) (transfer full): 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;
}
