/*
 * Copyright © 2013 Canonical 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/gdesktopappinfo.h>

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

#include <string.h>
#include <locale.h>

struct help_topic
{
  const gchar *command;
  const gchar *summary;
  const gchar *description;
  const gchar *synopsis;
};

struct help_substvar
{
  const gchar *var;
  const gchar *description;
};

static const struct help_topic topics[] = {
  { "help",         N_("Print help"),
                    N_("Print help"),
                    N_("[COMMAND]")
  },
  { "version",      N_("Print version"),
                    N_("Print version information and exit")
  },
  { "list-apps",    N_("List applications"),
                    N_("List the installed D-Bus activatable applications (by .desktop files)")
  },
  { "launch",       N_("Launch an application"),
                    N_("Launch the application (with optional files to open)"),
                    N_("APPID [FILE...]")
  },
  { "action",       N_("Activate an action"),
                    N_("Invoke an action on the application"),
                    N_("APPID ACTION [PARAMETER]")
  },
  { "list-actions", N_("List available actions"),
                    N_("List static actions for an application (from .desktop file)"),
                    N_("APPID")
  }
};

static const struct help_substvar substvars[] = {
  { N_("COMMAND"),   N_("The command to print detailed help for")                             },
  { N_("APPID"),     N_("Application identifier in D-Bus format (eg: org.example.viewer)")    },
  { N_("FILE"),      N_("Optional relative or absolute filenames, or URIs to open")           },
  { N_("ACTION"),    N_("The action name to invoke")                                          },
  { N_("PARAMETER"), N_("Optional parameter to the action invocation, in GVariant format")    }
};

static int
app_help (gboolean     requested,
          const gchar *command)
{
  const struct help_topic *topic = NULL;
  GString *string;

  string = g_string_new (NULL);

  if (command)
    {
      gint i;

      for (i = 0; i < G_N_ELEMENTS (topics); i++)
        if (g_str_equal (topics[i].command, command))
          topic = &topics[i];

      if (!topic)
        {
          g_string_printf (string, _("Unknown command %s\n\n"), command);
          requested = FALSE;
        }
    }

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

  if (topic)
    {
      gint maxwidth;
      gint i;

      g_string_append_printf (string, "\n  %s %s %s\n\n", "gapplication",
                              topic->command, topic->synopsis ? _(topic->synopsis) : "");
      g_string_append_printf (string, "%s\n\n", _(topic->description));

      if (topic->synopsis)
        {
          g_string_append (string, _("Arguments:\n"));

          maxwidth = 0;
          for (i = 0; i < G_N_ELEMENTS (substvars); i++)
            if (strstr (topic->synopsis, substvars[i].var))
              maxwidth = MAX(maxwidth, strlen (_(substvars[i].var)));

          for (i = 0; i < G_N_ELEMENTS (substvars); i++)
            if (strstr (topic->synopsis, substvars[i].var))
              g_string_append_printf (string, "  %-*.*s   %s\n", maxwidth, maxwidth,
                                      _(substvars[i].var), _(substvars[i].description));
          g_string_append (string, "\n");
        }
    }
  else
    {
      gint maxwidth;
      gint i;

      g_string_append_printf (string, "\n  %s %s %s\n\n", "gapplication", _("COMMAND"), _("[ARGS...]"));
      g_string_append_printf (string, _("Commands:\n"));

      maxwidth = 0;
      for (i = 0; i < G_N_ELEMENTS (topics); i++)
        maxwidth = MAX(maxwidth, strlen (topics[i].command));

      for (i = 0; i < G_N_ELEMENTS (topics); i++)
        g_string_append_printf (string, "  %-*.*s   %s\n", maxwidth, maxwidth,
                                topics[i].command, _(topics[i].summary));

      g_string_append (string, "\n");
      /* Translators: do not translate 'help', but please translate 'COMMAND'. */
      g_string_append_printf (string, _("Use '%s help COMMAND' to get detailed help.\n\n"), "gapplication");
    }

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

  g_string_free (string, TRUE);

  return requested ? 0 : 1;
}

static gboolean
app_check_name (gchar       **args,
                const gchar  *command)
{
  if (args[0] == NULL)
    {
      g_printerr (_("%s command requires an application id to directly follow\n\n"), command);
      return FALSE;
    }

  if (!g_dbus_is_name (args[0]))
    {
      g_printerr (_("invalid application id: '%s'\n"), args[0]);
      return FALSE;
    }

  return TRUE;
}

static int
app_no_args (const gchar *command)
{
  /* Translators: %s is replaced with a command name like 'list-actions' */
  g_printerr (_("'%s' takes no arguments\n\n"), command);
  return app_help (FALSE, command);
}

static int
app_version (gchar **args)
{
  if (g_strv_length (args))
    return app_no_args ("version");

  g_print (PACKAGE_VERSION "\n");
  return 0;
}

static int
app_list (gchar **args)
{
  GList *apps;

  if (g_strv_length (args))
    return app_no_args ("list");

  apps = g_app_info_get_all ();

  while (apps)
    {
      GDesktopAppInfo *info = apps->data;

      if (G_IS_DESKTOP_APP_INFO (info))
        if (g_desktop_app_info_get_boolean (info, "DBusActivatable"))
          {
            const gchar *filename;

            filename = g_app_info_get_id (G_APP_INFO (info));
            if (g_str_has_suffix (filename, ".desktop"))
              {
                gchar *id;

                id = g_strndup (filename, strlen (filename) - 8);
                g_print ("%s\n", id);
                g_free (id);
              }
          }

      apps = g_list_delete_link (apps, apps);
      g_object_unref (info);
    }

  return 0;
}

static gchar *
app_path_for_id (const gchar *app_id)
{
  gchar *path;
  gint i;

  path = g_strconcat ("/", app_id, NULL);
  for (i = 0; path[i]; i++)
    {
      if (path[i] == '.')
        path[i] = '/';
      if (path[i] == '-')
        path[i] = '_';
    }

  return path;
}

static int
app_call (const gchar *app_id,
          const gchar *method_name,
          GVariant    *parameters)
{
  GDBusConnection *session;
  GError *error = NULL;
  gchar *object_path;
  GVariant *result;


  session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
  if (!session)
    {
      g_variant_unref (g_variant_ref_sink (parameters));
      g_printerr (_("unable to connect to D-Bus: %s\n"), error->message);
      g_error_free (error);
      return 1;
    }

  object_path = app_path_for_id (app_id);

  result = g_dbus_connection_call_sync (session, app_id, object_path, "org.freedesktop.Application",
                                        method_name, parameters, G_VARIANT_TYPE_UNIT,
                                        G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);

  g_free (object_path);

  if (result)
    {
      g_variant_unref (result);
      return 0;
    }
  else
    {
      g_printerr (_("error sending %s message to application: %s\n"), method_name, error->message);
      g_error_free (error);
      return 1;
    }
}

static GVariant *
app_get_platform_data (void)
{
  GVariantBuilder builder;
  const gchar *startup_id;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);

  if ((startup_id = g_getenv ("DESKTOP_STARTUP_ID")))
    g_variant_builder_add (&builder, "{sv}", "desktop-startup-id", g_variant_new_string (startup_id));

  return g_variant_builder_end (&builder);
}

static int
app_action (gchar **args)
{
  GVariantBuilder params;
  const gchar *name;

  if (!app_check_name (args, "action"))
    return 1;

  if (args[1] == NULL)
    {
      g_printerr (_("action name must be given after application id\n"));
      return 1;
    }

  name = args[1];

  if (!g_action_name_is_valid (name))
    {
      g_printerr (_("invalid action name: '%s'\n"
                    "action names must consist of only alphanumerics, '-' and '.'\n"), name);
      return 1;
    }

  g_variant_builder_init (&params, G_VARIANT_TYPE ("av"));

  if (args[2])
    {
      GError *error = NULL;
      GVariant *parameter;

      parameter = g_variant_parse (NULL, args[2], NULL, NULL, &error);

      if (!parameter)
        {
          gchar *context;

          context = g_variant_parse_error_print_context (error, args[2]);
          g_printerr (_("error parsing action parameter: %s\n"), context);
          g_variant_builder_clear (&params);
          g_error_free (error);
          g_free (context);
          return 1;
        }

      g_variant_builder_add (&params, "v", parameter);
      g_variant_unref (parameter);

      if (args[3])
        {
          g_printerr (_("actions accept a maximum of one parameter\n"));
          g_variant_builder_clear (&params);
          return 1;
        }
    }

  return app_call (args[0], "ActivateAction", g_variant_new ("(sav@a{sv})", name, &params, app_get_platform_data ()));
}

static int
app_activate (const gchar *app_id)
{
  return app_call (app_id, "Activate", g_variant_new ("(@a{sv})", app_get_platform_data ()));
}

static int
app_launch (gchar **args)
{
  GVariantBuilder files;
  gint i;

  if (!app_check_name (args, "launch"))
    return 1;

  if (args[1] == NULL)
    return app_activate (args[0]);

  g_variant_builder_init (&files, G_VARIANT_TYPE_STRING_ARRAY);

  for (i = 1; args[i]; i++)
    {
      GFile *file;

      /* "This operation never fails" */
      file = g_file_new_for_commandline_arg (args[i]);
      g_variant_builder_add_value (&files, g_variant_new_take_string (g_file_get_uri (file)));
      g_object_unref (file);
    }

  return app_call (args[0], "Open", g_variant_new ("(as@a{sv})", &files, app_get_platform_data ()));
}

static int
app_list_actions (gchar **args)
{
  const gchar * const *actions;
  GDesktopAppInfo *app_info;
  gchar *filename;
  gint i;

  if (!app_check_name (args, "list-actions"))
    return 1;

  if (args[1])
    {
      g_printerr (_("list-actions command takes only the application id"));
      app_help (FALSE, "list-actions");
    }

  filename = g_strconcat (args[0], ".desktop", NULL);
  app_info = g_desktop_app_info_new (filename);
  g_free (filename);

  if (app_info == NULL)
    {
      g_printerr (_("unable to find desktop file for application %s\n"), args[0]);
      return 1;
    }

  actions = g_desktop_app_info_list_actions (app_info);

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

  g_object_unref (app_info);

  return 0;
}

int
main (int argc, char **argv)
{
  setlocale (LC_ALL, "");
  textdomain (GETTEXT_PACKAGE);
  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif

  if (argc < 2)
    return app_help (TRUE, NULL);

  if (g_str_equal (argv[1], "help"))
    return app_help (TRUE, argv[2]);

  if (g_str_equal (argv[1], "version"))
    return app_version (argv + 2);

  if (g_str_equal (argv[1], "list-apps"))
    return app_list (argv + 2);

  if (g_str_equal (argv[1], "launch"))
    return app_launch (argv + 2);

  if (g_str_equal (argv[1], "action"))
    return app_action (argv + 2);

  if (g_str_equal (argv[1], "list-actions"))
    return app_list_actions (argv + 2);

  g_printerr (_("unrecognised command: %s\n\n"), argv[1]);

  return app_help (FALSE, NULL);
}
