/*
 * Copyright 2015 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 licence, 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: Matthias Clasen <mclasen@redhat.com>
 */

#include "config.h"

#include <gio/gio.h>
#include <gi18n.h>

#include "gio-tool.h"


static char *attributes = NULL;
static gboolean show_hidden = FALSE;
static gboolean show_long = FALSE;
static gboolean nofollow_symlinks = FALSE;
static gboolean print_uris = FALSE;

static const GOptionEntry entries[] = {
  { "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, N_("The attributes to get"), N_("ATTRIBUTES") },
  { "hidden", 'h', 0, G_OPTION_ARG_NONE, &show_hidden, N_("Show hidden files"), NULL },
  { "long", 'l', 0, G_OPTION_ARG_NONE, &show_long, N_("Use a long listing format"), NULL },
  { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don't follow symbolic links"), NULL},
  { "print-uris", 'u', 0, G_OPTION_ARG_NONE, &print_uris, N_("Print full URIs"), NULL},
  { NULL }
};

static void
show_file_listing (GFileInfo *info, GFile *parent)
{
  const char *name, *type;
  char *uri = NULL;
  goffset size;
  char **attributes;
  int i;
  gboolean first_attr;
  GFile *child;

  if ((g_file_info_get_is_hidden (info)) && !show_hidden)
    return;

  name = g_file_info_get_name (info);
  if (name == NULL)
    name = "";

  if (print_uris) {
    child = g_file_get_child (parent, name);
    uri = g_file_get_uri (child);
    g_object_unref (child);
  }

  size = g_file_info_get_size (info);
  type = file_type_to_string (g_file_info_get_file_type (info));
  if (show_long)
    g_print ("%s\t%"G_GUINT64_FORMAT"\t(%s)", print_uris? uri: name, (guint64)size, type);
  else
    g_print ("%s", print_uris? uri: name);

  if (print_uris)
    g_free (uri);

  first_attr = TRUE;
  attributes = g_file_info_list_attributes (info, NULL);
  for (i = 0 ; attributes[i] != NULL; i++)
    {
      char *val_as_string;

      if (!show_long ||
          strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_NAME) == 0 ||
          strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_SIZE) == 0 ||
          strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_TYPE) == 0 ||
          strcmp (attributes[i], G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) == 0)
        continue;

      if (first_attr)
        {
          g_print ("\t");
          first_attr = FALSE;
        }
      else
        g_print (" ");
      val_as_string = g_file_info_get_attribute_as_string (info, attributes[i]);
      g_print ("%s=%s", attributes[i], val_as_string);
      g_free (val_as_string);
    }

  g_strfreev (attributes);

  g_print ("\n");
}

static gboolean
list (GFile *file)
{
  GFileEnumerator *enumerator;
  GFileInfo *info;
  GError *error;
  gboolean res;

  error = NULL;
  enumerator = g_file_enumerate_children (file,
                                          attributes,
                                          nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : 0,
                                          NULL,
                                          &error);
  if (enumerator == NULL)
    {
      print_file_error (file, error->message);
      g_error_free (error);
      return FALSE;
    }

  res = TRUE;
  while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)
    {
      show_file_listing (info, file);
      g_object_unref (info);
    }

  if (error)
    {
      print_file_error (file, error->message);
      g_clear_error (&error);
      res = FALSE;
    }

  if (!g_file_enumerator_close (enumerator, NULL, &error))
    {
      print_file_error (file, error->message);
      g_clear_error (&error);
      res = FALSE;
    }

  return res;
}

int
handle_list (int argc, char *argv[], gboolean do_help)
{
  GOptionContext *context;
  gchar *param;
  GError *error = NULL;
  gboolean res;
  gint i;
  GFile *file;

  g_set_prgname ("gio list");

  /* Translators: commandline placeholder */
  param = g_strdup_printf ("[%s...]", _("LOCATION"));
  context = g_option_context_new (param);
  g_free (param);
  g_option_context_set_help_enabled (context, FALSE);
  g_option_context_set_summary (context,
      _("List the contents of the locations."));
  g_option_context_set_description (context,
      _("gio list is similar to the traditional ls utility, but using GIO\n"
        "locations instead of local files: for example, you can use something\n"
        "like smb://server/resource/file.txt as location. File attributes can\n"
        "be specified with their GIO name, e.g. standard::icon"));
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);

  if (do_help)
    {
      show_help (context, NULL);
      return 0;
    }

  if (!g_option_context_parse (context, &argc, &argv, &error))
    {
      show_help (context, error->message);
      g_error_free (error);
      return 1;
    }

  g_option_context_free (context);

  if (attributes != NULL)
    show_long = TRUE;

  attributes = g_strconcat (G_FILE_ATTRIBUTE_STANDARD_NAME ","
                            G_FILE_ATTRIBUTE_STANDARD_TYPE ","
                            G_FILE_ATTRIBUTE_STANDARD_SIZE ","
                            G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
                            attributes != NULL ? "," : "",
                            attributes,
                            NULL);

  res = TRUE;
  if (argc > 1)
    {
      for (i = 1; i < argc; i++)
        {
          file = g_file_new_for_commandline_arg (argv[i]);
          res &= list (file);
          g_object_unref (file);
        }
    }
  else
    {
      char *cwd;

      cwd = g_get_current_dir ();
      file = g_file_new_for_path (cwd);
      res = list (file);
      g_object_unref (file);
      g_free (cwd);
    }

  g_free (attributes);

  return res ? 0 : 2;
}
