/*
 * 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 <stdlib.h>

#include "gio-tool.h"


static char *attr_type = "string";
static gboolean nofollow_symlinks = FALSE;

static const GOptionEntry entries[] = {
  { "type", 't', 0, G_OPTION_ARG_STRING, &attr_type, N_("Type of the attribute"), N_("TYPE") },
  { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, N_("Don’t follow symbolic links"), NULL },
  { NULL }
};

static char *
hex_unescape (const char *str)
{
  int i;
  char *unescaped_str, *p;
  unsigned char c;
  int len;

  len = strlen (str);
  unescaped_str = g_malloc (len + 1);

  p = unescaped_str;
  for (i = 0; i < len; i++)
    {
      if (str[i] == '\\' &&
	  str[i+1] == 'x' &&
	  len - i >= 4)
	{
	  c =
	    (g_ascii_xdigit_value (str[i+2]) << 4) |
	    g_ascii_xdigit_value (str[i+3]);
	  *p++ = c;
	  i += 3;
	}
      else
	*p++ = str[i];
    }
  *p++ = 0;

  return unescaped_str;
}

int
handle_set (int argc, char *argv[], gboolean do_help)
{
  GOptionContext *context;
  GError *error = NULL;
  GFile *file;
  const char *attribute;
  GFileAttributeType type;
  gpointer value;
  gboolean b;
  guint32 uint32;
  gint32 int32;
  guint64 uint64;
  gint64 int64;
  gchar *param;

  g_set_prgname ("gio set");

  /* Translators: commandline placeholder */
  param = g_strdup_printf ("%s %s %s...", _("LOCATION"), _("ATTRIBUTE"), _("VALUE"));
  context = g_option_context_new (param);
  g_free (param);
  g_option_context_set_help_enabled (context, FALSE);
  g_option_context_set_summary (context, _("Set a file attribute of LOCATION."));
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);

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

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

  if (argc < 2)
    {
      show_help (context, _("Location not specified"));
      g_option_context_free (context);
      return 1;
    }

  if (argc < 3)
    {
      show_help (context, _("Attribute not specified"));
      g_option_context_free (context);
      return 1;
    }

  attribute = argv[2];

  type = attribute_type_from_string (attr_type);
  if ((argc < 4) && (type != G_FILE_ATTRIBUTE_TYPE_INVALID))
    {
      show_help (context, _("Value not specified"));
      g_option_context_free (context);
      return 1;
    }

  if ((argc > 4) && (type != G_FILE_ATTRIBUTE_TYPE_STRINGV))
    {
      show_help (context, _("Too many arguments"));
      g_option_context_free (context);
      return 1;
    }

  g_option_context_free (context);

  switch (type)
    {
    case G_FILE_ATTRIBUTE_TYPE_STRING:
      value = argv[3];
      break;
    case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
      value = hex_unescape (argv[3]);
      break;
    case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
      b = g_ascii_strcasecmp (argv[3], "true") == 0;
      value = &b;
      break;
    case G_FILE_ATTRIBUTE_TYPE_UINT32:
      uint32 = atol (argv[3]);
      value = &uint32;
      break;
    case G_FILE_ATTRIBUTE_TYPE_INT32:
      int32 = atol (argv[3]);
      value = &int32;
      break;
    case G_FILE_ATTRIBUTE_TYPE_UINT64:
      uint64 = g_ascii_strtoull (argv[3], NULL, 10);
      value = &uint64;
      break;
    case G_FILE_ATTRIBUTE_TYPE_INT64:
      int64 = g_ascii_strtoll (argv[3], NULL, 10);
      value = &int64;
      break;
    case G_FILE_ATTRIBUTE_TYPE_STRINGV:
      value = &argv[3];
      break;
    case G_FILE_ATTRIBUTE_TYPE_INVALID:
      value = NULL;
      break;
    case G_FILE_ATTRIBUTE_TYPE_OBJECT:
    default:
      print_error (_("Invalid attribute type “%s”"), attr_type);
      return 1;
    }

  file = g_file_new_for_commandline_arg (argv[1]);

  if (!g_file_set_attribute (file,
			     attribute,
			     type,
			     value,
                             nofollow_symlinks ?
                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS :
                               G_FILE_QUERY_INFO_NONE,
                             NULL, &error))
    {
      print_error ("%s", error->message);
      g_error_free (error);
      g_object_unref (file);
      return 1;
    }

  g_object_unref (file);

  return 0;
}
