/*
 * Copyright © 2010 Codethink Limited
 *
 * 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: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include <gio/gio.h>
#include <gi18n.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>

#ifdef G_OS_WIN32
#include "glib/glib-private.h"
#endif

static GSettingsSchemaSource   *global_schema_source;
static GSettings               *global_settings;
static GSettingsSchema         *global_schema;
static GSettingsSchemaKey      *global_schema_key;
const gchar                    *global_key;
const gchar                    *global_value;

static gboolean
is_relocatable_schema (GSettingsSchema *schema)
{
  return g_settings_schema_get_path (schema) == NULL;
}

static gboolean
check_relocatable_schema (GSettingsSchema *schema,
                          const gchar     *schema_id)
{
  if (schema == NULL)
    {
      g_printerr (_("No such schema '%s'\n"), schema_id);
      return FALSE;
    }

  if (!is_relocatable_schema (schema))
    {
      g_printerr (_("Schema '%s' is not relocatable "
                    "(path must not be specified)\n"),
                  schema_id);
      return FALSE;
    }

  return TRUE;
}

static gboolean
check_schema (GSettingsSchema *schema,
              const gchar *schema_id)
{
  if (schema == NULL)
    {
      g_printerr (_("No such schema '%s'\n"), schema_id);
      return FALSE;
    }

  if (is_relocatable_schema (schema))
    {
      g_printerr (_("Schema '%s' is relocatable "
                    "(path must be specified)\n"),
                  schema_id);
      return FALSE;
    }

  return TRUE;
}

static gboolean
check_path (const gchar *path)
{
  if (path[0] == '\0')
    {
      g_printerr (_("Empty path given.\n"));
      return FALSE;
    }

  if (path[0] != '/')
    {
      g_printerr (_("Path must begin with a slash (/)\n"));
      return FALSE;
    }

  if (!g_str_has_suffix (path, "/"))
    {
      g_printerr (_("Path must end with a slash (/)\n"));
      return FALSE;
    }

  if (strstr (path, "//"))
    {
      g_printerr (_("Path must not contain two adjacent slashes (//)\n"));
      return FALSE;
    }

  return TRUE;
}

static void
output_list (gchar **list)
{
  gint i;

  for (i = 0; list[i]; i++)
    g_print ("%s\n", list[i]);
}

static void
gsettings_print_version (void)
{
  g_print ("%d.%d.%d\n", glib_major_version, glib_minor_version,
           glib_micro_version);
}

static void
gsettings_list_schemas (void)
{
  gchar **schemas;

  g_settings_schema_source_list_schemas (global_schema_source, TRUE, &schemas, NULL);
  output_list (schemas);
  g_strfreev (schemas);
}

static void
gsettings_list_relocatable_schemas (void)
{
  gchar **schemas;

  g_settings_schema_source_list_schemas (global_schema_source, TRUE, NULL, &schemas);
  output_list (schemas);
  g_strfreev (schemas);
}

static void
gsettings_list_keys (void)
{
  gchar **keys;

  keys = g_settings_schema_list_keys (global_schema);
  output_list (keys);
  g_strfreev (keys);
}

static void
gsettings_list_children (void)
{
  gchar **children;
  gint max = 0;
  gint i;

  children = g_settings_list_children (global_settings);
  for (i = 0; children[i]; i++)
    if (strlen (children[i]) > max)
      max = strlen (children[i]);

  for (i = 0; children[i]; i++)
    {
      GSettings *child;
      GSettingsSchema *schema;
      gchar *path;

      child = g_settings_get_child (global_settings, children[i]);
      g_object_get (child,
                    "settings-schema", &schema,
                    "path", &path,
                    NULL);

      if (g_settings_schema_get_path (schema) != NULL)
        g_print ("%-*s   %s\n", max, children[i], g_settings_schema_get_id (schema));
      else
        g_print ("%-*s   %s:%s\n", max, children[i], g_settings_schema_get_id (schema), path);

      g_object_unref (child);
      g_settings_schema_unref (schema);
      g_free (path);
    }

  g_strfreev (children);
}

static void
enumerate (GSettings *settings)
{
  gchar **keys;
  GSettingsSchema *schema;
  gint i;

  g_object_get (settings, "settings-schema", &schema, NULL);

  keys = g_settings_schema_list_keys (schema);
  for (i = 0; keys[i]; i++)
    {
      GVariant *value;
      gchar *printed;

      value = g_settings_get_value (settings, keys[i]);
      printed = g_variant_print (value, TRUE);
      g_print ("%s %s %s\n", g_settings_schema_get_id (schema), keys[i], printed);
      g_variant_unref (value);
      g_free (printed);
    }

  g_settings_schema_unref (schema);
  g_strfreev (keys);
}

static void
list_recursively (GSettings *settings)
{
  gchar **children;
  gint i;

  enumerate (settings);
  children = g_settings_list_children (settings);
  for (i = 0; children[i]; i++)
    {
      GSettings *child;

      child = g_settings_get_child (settings, children[i]);
      list_recursively (child);
      g_object_unref (child);
    }

  g_strfreev (children);
}

static void
gsettings_list_recursively (void)
{
  if (global_settings)
    {
      list_recursively (global_settings);
    }
  else
    {
      gchar **schemas;
      gint i;

      g_settings_schema_source_list_schemas (global_schema_source, TRUE, &schemas, NULL);

      for (i = 0; schemas[i]; i++)
        {
          GSettings *settings;

          settings = g_settings_new (schemas[i]);
          list_recursively (settings);
          g_object_unref (settings);
        }

      g_strfreev (schemas);
    }
}

static void
gsettings_range (void)
{
  GVariant *range, *detail;
  const gchar *type;

  range = g_settings_schema_key_get_range (global_schema_key);
  g_variant_get (range, "(&sv)", &type, &detail);

  if (strcmp (type, "type") == 0)
    g_print ("type %s\n", g_variant_get_type_string (detail) + 1);

  else if (strcmp (type, "range") == 0)
    {
      GVariant *min, *max;
      gchar *smin, *smax;

      g_variant_get (detail, "(**)", &min, &max);
      smin = g_variant_print (min, FALSE);
      smax = g_variant_print (max, FALSE);

      g_print ("range %s %s %s\n",
               g_variant_get_type_string (min), smin, smax);
      g_variant_unref (min);
      g_variant_unref (max);
      g_free (smin);
      g_free (smax);
    }

  else if (strcmp (type, "enum") == 0 || strcmp (type, "flags") == 0)
    {
      GVariantIter iter;
      GVariant *item;

      g_print ("%s\n", type);

      g_variant_iter_init (&iter, detail);
      while (g_variant_iter_loop (&iter, "*", &item))
        {
          gchar *printed;

          printed = g_variant_print (item, FALSE);
          g_print ("%s\n", printed);
          g_free (printed);
        }
    }

  g_variant_unref (detail);
  g_variant_unref (range);
}

static void
gsettings_get (void)
{
  GVariant *value;
  gchar *printed;

  value = g_settings_get_value (global_settings, global_key);
  printed = g_variant_print (value, TRUE);
  g_print ("%s\n", printed);
  g_variant_unref (value);
  g_free (printed);
}

static void
gsettings_reset (void)
{
  g_settings_reset (global_settings, global_key);
  g_settings_sync ();
}

static void
reset_all_keys (GSettings *settings)
{
  GSettingsSchema *schema;
  gchar **keys;
  gint i;

  g_object_get (settings, "settings-schema", &schema, NULL);

  keys = g_settings_schema_list_keys (schema);
  for (i = 0; keys[i]; i++)
    {
      g_settings_reset (settings, keys[i]);
    }

  g_settings_schema_unref (schema);
  g_strfreev (keys);
}

static void
gsettings_reset_recursively (void)
{
  gchar **children;
  gint i;

  g_settings_delay (global_settings);

  reset_all_keys (global_settings);
  children = g_settings_list_children (global_settings);
  for (i = 0; children[i]; i++)
    {
      GSettings *child;
      child = g_settings_get_child (global_settings, children[i]);

      reset_all_keys (child);

      g_object_unref (child);
    }

  g_strfreev (children);

  g_settings_apply (global_settings);
  g_settings_sync ();
}

static void
gsettings_writable (void)
{
  g_print ("%s\n",
           g_settings_is_writable (global_settings, global_key) ?
           "true" : "false");
}

static void
value_changed (GSettings   *settings,
               const gchar *key,
               gpointer     user_data)
{
  GVariant *value;
  gchar *printed;

  value = g_settings_get_value (settings, key);
  printed = g_variant_print (value, TRUE);
  g_print ("%s: %s\n", key, printed);
  g_variant_unref (value);
  g_free (printed);
}

static void
gsettings_monitor (void)
{
  if (global_key)
    {
      gchar *name;

      name = g_strdup_printf ("changed::%s", global_key);
      g_signal_connect (global_settings, name, G_CALLBACK (value_changed), NULL);
    }
  else
    g_signal_connect (global_settings, "changed", G_CALLBACK (value_changed), NULL);

  for (;;)
    g_main_context_iteration (NULL, TRUE);
}

static void
gsettings_set (void)
{
  const GVariantType *type;
  GError *error = NULL;
  GVariant *new;
  gchar *freeme = NULL;

  type = g_settings_schema_key_get_value_type (global_schema_key);

  new = g_variant_parse (type, global_value, NULL, NULL, &error);

  /* If that didn't work and the type is string then we should assume
   * that the user is just trying to set a string directly and forgot
   * the quotes (or had them consumed by the shell).
   *
   * If the user started with a quote then we assume that some deeper
   * problem is at play and we want the failure in that case.
   *
   * Consider:
   *
   *   gsettings set x.y.z key "'i don't expect this to work'"
   *
   * Note that we should not just add quotes and try parsing again, but
   * rather assume that the user is providing us with a bare string.
   * Assume we added single quotes, then consider this case:
   *
   *   gsettings set x.y.z key "i'd expect this to work"
   *
   * A similar example could be given for double quotes.
   *
   * Avoid that whole mess by just using g_variant_new_string().
   */
  if (new == NULL &&
      g_variant_type_equal (type, G_VARIANT_TYPE_STRING) &&
      global_value[0] != '\'' && global_value[0] != '"')
    {
      g_clear_error (&error);
      new = g_variant_new_string (global_value);
    }

  if (new == NULL)
    {
      gchar *context;

      context = g_variant_parse_error_print_context (error, global_value);
      g_printerr ("%s", context);
      exit (1);
    }

  if (!g_settings_schema_key_range_check (global_schema_key, new))
    {
      g_printerr (_("The provided value is outside of the valid range\n"));
      g_variant_unref (new);
      exit (1);
    }

  if (!g_settings_set_value (global_settings, global_key, new))
    {
      g_printerr (_("The key is not writable\n"));
      exit (1);
    }

  g_settings_sync ();

  g_free (freeme);
}

static int
gsettings_help (gboolean     requested,
                const gchar *command)
{
  const gchar *description;
  const gchar *synopsis;
  GString *string;

  string = g_string_new (NULL);

  if (command == NULL)
    ;

  else if (strcmp (command, "help") == 0)
    {
      description = _("Print help");
      synopsis = "[COMMAND]";
    }

  else if (strcmp (command, "--version") == 0)
    {
      description = _("Print version information and exit");
      synopsis = "";
    }

  else if (strcmp (command, "list-schemas") == 0)
    {
      description = _("List the installed (non-relocatable) schemas");
      synopsis = "";
    }

  else if (strcmp (command, "list-relocatable-schemas") == 0)
    {
      description = _("List the installed relocatable schemas");
      synopsis = "";
    }

  else if (strcmp (command, "list-keys") == 0)
    {
      description = _("List the keys in SCHEMA");
      synopsis = N_("SCHEMA[:PATH]");
    }

  else if (strcmp (command, "list-children") == 0)
    {
      description = _("List the children of SCHEMA");
      synopsis = N_("SCHEMA[:PATH]");
    }

  else if (strcmp (command, "list-recursively") == 0)
    {
      description = _("List keys and values, recursively\n"
                      "If no SCHEMA is given, list all keys\n");
      synopsis = N_("[SCHEMA[:PATH]]");
    }

  else if (strcmp (command, "get") == 0)
    {
      description = _("Get the value of KEY");
      synopsis = N_("SCHEMA[:PATH] KEY");
    }

  else if (strcmp (command, "range") == 0)
    {
      description = _("Query the range of valid values for KEY");
      synopsis = N_("SCHEMA[:PATH] KEY");
    }

  else if (strcmp (command, "set") == 0)
    {
      description = _("Set the value of KEY to VALUE");
      synopsis = N_("SCHEMA[:PATH] KEY VALUE");
    }

  else if (strcmp (command, "reset") == 0)
    {
      description = _("Reset KEY to its default value");
      synopsis = N_("SCHEMA[:PATH] KEY");
    }

  else if (strcmp (command, "reset-recursively") == 0)
    {
      description = _("Reset all keys in SCHEMA to their defaults");
      synopsis = N_("SCHEMA[:PATH]");
    }

  else if (strcmp (command, "writable") == 0)
    {
      description = _("Check if KEY is writable");
      synopsis = N_("SCHEMA[:PATH] KEY");
    }

  else if (strcmp (command, "monitor") == 0)
    {
      description = _("Monitor KEY for changes.\n"
                    "If no KEY is specified, monitor all keys in SCHEMA.\n"
                    "Use ^C to stop monitoring.\n");
      synopsis = N_("SCHEMA[:PATH] [KEY]");
    }
  else
    {
      g_string_printf (string, _("Unknown command %s\n\n"), command);
      requested = FALSE;
      command = NULL;
    }

  if (command == NULL)
    {
      g_string_append (string,
      _("Usage:\n"
        "  gsettings --version\n"
        "  gsettings [--schemadir SCHEMADIR] COMMAND [ARGS...]\n"
        "\n"
        "Commands:\n"
        "  help                      Show this information\n"
        "  list-schemas              List installed schemas\n"
        "  list-relocatable-schemas  List relocatable schemas\n"
        "  list-keys                 List keys in a schema\n"
        "  list-children             List children of a schema\n"
        "  list-recursively          List keys and values, recursively\n"
        "  range                     Queries the range of a key\n"
        "  get                       Get the value of a key\n"
        "  set                       Set the value of a key\n"
        "  reset                     Reset the value of a key\n"
        "  reset-recursively         Reset all values in a given schema\n"
        "  writable                  Check if a key is writable\n"
        "  monitor                   Watch for changes\n"
        "\n"
        "Use 'gsettings help COMMAND' to get detailed help.\n\n"));
    }
  else
    {
      g_string_append_printf (string, _("Usage:\n  gsettings [--schemadir SCHEMADIR] %s %s\n\n%s\n\n"),
                              command, synopsis[0] ? _(synopsis) : "", description);

      g_string_append (string, _("Arguments:\n"));

      g_string_append (string,
                       _("  SCHEMADIR A directory to search for additional schemas\n"));

      if (strstr (synopsis, "[COMMAND]"))
        g_string_append (string,
                       _("  COMMAND   The (optional) command to explain\n"));

      else if (strstr (synopsis, "SCHEMA"))
        g_string_append (string,
                       _("  SCHEMA    The name of the schema\n"
                         "  PATH      The path, for relocatable schemas\n"));

      if (strstr (synopsis, "[KEY]"))
        g_string_append (string,
                       _("  KEY       The (optional) key within the schema\n"));

      else if (strstr (synopsis, "KEY"))
        g_string_append (string,
                       _("  KEY       The key within the schema\n"));

      if (strstr (synopsis, "VALUE"))
        g_string_append (string,
                       _("  VALUE     The value to set\n"));

      g_string_append (string, "\n");
    }

  if (requested)
    g_print ("%s", string->str);
  else
    g_printerr ("%s\n", string->str);

  g_string_free (string, TRUE);

  return requested ? 0 : 1;
}


int
main (int argc, char **argv)
{
  void (* function) (void);
  gboolean need_settings;

#ifdef G_OS_WIN32
  gchar *tmp;
#endif

  setlocale (LC_ALL, "");
  textdomain (GETTEXT_PACKAGE);

#ifdef G_OS_WIN32
  tmp = _glib_get_locale_dir ();
  bindtextdomain (GETTEXT_PACKAGE, tmp);
  g_free (tmp);
#else
  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
#endif

#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  if (argc < 2)
    return gsettings_help (FALSE, NULL);

  global_schema_source = g_settings_schema_source_ref (g_settings_schema_source_get_default ());

  if (argc > 3 && g_str_equal (argv[1], "--schemadir"))
    {
      GSettingsSchemaSource *parent = global_schema_source;
      GError *error = NULL;

      global_schema_source = g_settings_schema_source_new_from_directory (argv[2], parent, FALSE, &error);
      g_settings_schema_source_unref (parent);

      if (global_schema_source == NULL)
        {
          g_printerr (_("Could not load schemas from %s: %s\n"), argv[2], error->message);
          g_clear_error (&error);

          return 1;
        }

      /* shift remaining arguments (not correct wrt argv[0], but doesn't matter) */
      argv = argv + 2;
      argc -= 2;
    }

  need_settings = TRUE;

  if (strcmp (argv[1], "help") == 0)
    return gsettings_help (TRUE, argv[2]);

  else if (argc == 2 && strcmp (argv[1], "--version") == 0)
    function = gsettings_print_version;

  else if (argc == 2 && strcmp (argv[1], "list-schemas") == 0)
    function = gsettings_list_schemas;

  else if (argc == 2 && strcmp (argv[1], "list-relocatable-schemas") == 0)
    function = gsettings_list_relocatable_schemas;

  else if (argc == 3 && strcmp (argv[1], "list-keys") == 0)
    {
      need_settings = FALSE;
      function = gsettings_list_keys;
    }

  else if (argc == 3 && strcmp (argv[1], "list-children") == 0)
    function = gsettings_list_children;

  else if ((argc == 2 || argc == 3) && strcmp (argv[1], "list-recursively") == 0)
    function = gsettings_list_recursively;

  else if (argc == 4 && strcmp (argv[1], "range") == 0)
    {
      need_settings = FALSE;
      function = gsettings_range;
    }

  else if (argc == 4 && strcmp (argv[1], "get") == 0)
    function = gsettings_get;

  else if (argc == 5 && strcmp (argv[1], "set") == 0)
    function = gsettings_set;

  else if (argc == 4 && strcmp (argv[1], "reset") == 0)
    function = gsettings_reset;

  else if (argc == 3 && strcmp (argv[1], "reset-recursively") == 0)
    function = gsettings_reset_recursively;

  else if (argc == 4 && strcmp (argv[1], "writable") == 0)
    function = gsettings_writable;

  else if ((argc == 3 || argc == 4) && strcmp (argv[1], "monitor") == 0)
    function = gsettings_monitor;

  else
    return gsettings_help (FALSE, argv[1]);

  if (argc > 2)
    {
      gchar **parts;

      if (argv[2][0] == '\0')
        {
          g_printerr (_("Empty schema name given\n"));
          return 1;
        }

      parts = g_strsplit (argv[2], ":", 2);

      global_schema = g_settings_schema_source_lookup (global_schema_source, parts[0], TRUE);

      if (need_settings)
        {
          if (parts[1])
            {
              if (!check_relocatable_schema (global_schema, parts[0]) || !check_path (parts[1]))
                return 1;

              global_settings = g_settings_new_full (global_schema, NULL, parts[1]);
            }
          else
            {
              if (!check_schema (global_schema, parts[0]))
                return 1;

              global_settings = g_settings_new_full (global_schema, NULL, NULL);
            }
        }
      else
        {
          /* If the user has given a path then we enforce that we have a
           * relocatable schema, but if they didn't give a path then it
           * doesn't matter what type of schema we have (since it's
           * reasonable to ask for introspection information on a
           * relocatable schema without having to give the path).
           */
          if (parts[1])
            {
              if (!check_relocatable_schema (global_schema, parts[0]) || !check_path (parts[1]))
                return 1;
            }
          else
            {
              if (global_schema == NULL)
                {
                  g_printerr (_("No such schema '%s'\n"), parts[0]);
                  return 1;
                }
            }
        }

      g_strfreev (parts);
    }

  if (argc > 3)
    {
      if (!g_settings_schema_has_key (global_schema, argv[3]))
        {
          g_printerr (_("No such key '%s'\n"), argv[3]);
          return 1;
        }

      global_key = argv[3];
      global_schema_key = g_settings_schema_get_key (global_schema, global_key);
    }

  if (argc > 4)
    global_value = argv[4];

  (* function) ();


  g_clear_pointer (&global_schema_source, g_settings_schema_source_unref);
  g_clear_pointer (&global_schema_key, g_settings_schema_key_unref);
  g_clear_pointer (&global_schema, g_settings_schema_unref);
  g_clear_object (&global_settings);

  return 0;
}
