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

#include "config.h"

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

#include "gio-tool.h"

static gchar **watch_dirs;
static gchar **watch_files;
static gchar **watch_direct;
static gchar **watch_silent;
static gchar **watch_default;
static gboolean no_moves;
static gboolean mounts;

static const GOptionEntry entries[] = {
  { "dir", 'd', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_dirs,
      N_("Monitor a directory (default: depends on type)"), N_("LOCATION") },
  { "file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_files,
      N_("Monitor a file (default: depends on type)"), N_("LOCATION") },
  { "direct", 'D', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_direct,
      N_("Monitor a file directly (notices changes made via hardlinks)"), N_("LOCATION") },
  { "silent", 's', 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_silent,
      N_("Monitors a file directly, but doesn’t report changes"), N_("LOCATION") },
  { "no-moves", 'n', 0, G_OPTION_ARG_NONE, &no_moves,
      N_("Report moves and renames as simple deleted/created events"), NULL },
  { "mounts", 'm', 0, G_OPTION_ARG_NONE, &mounts,
      N_("Watch for mount events"), NULL },
  { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &watch_default,
      NULL, NULL },
  G_OPTION_ENTRY_NULL
};

static void
watch_callback (GFileMonitor      *monitor,
                GFile             *child,
                GFile             *other,
                GFileMonitorEvent  event_type,
                gpointer           user_data)
{
  gchar *child_str;
  gchar *other_str;

  g_assert (child);

  if (g_file_is_native (child))
    child_str = g_file_get_path (child);
  else
    child_str = g_file_get_uri (child);

  if (other)
    {
      if (g_file_is_native (other))
        other_str = g_file_get_path (other);
      else
        other_str = g_file_get_uri (other);
    }
  else
    other_str = g_strdup ("(none)");

  g_print ("%s: ", (gchar *) user_data);
  switch (event_type)
    {
    case G_FILE_MONITOR_EVENT_CHANGED:
      g_assert (!other);
      g_print ("%s: changed", child_str);
      break;
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
      g_assert (!other);
      g_print ("%s: changes done", child_str);
      break;
    case G_FILE_MONITOR_EVENT_DELETED:
      g_assert (!other);
      g_print ("%s: deleted", child_str);
      break;
    case G_FILE_MONITOR_EVENT_CREATED:
      g_assert (!other);
      g_print ("%s: created", child_str);
      break;
    case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
      g_assert (!other);
      g_print ("%s: attributes changed", child_str);
      break;
    case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
      g_assert (!other);
      g_print ("%s: pre-unmount", child_str);
      break;
    case G_FILE_MONITOR_EVENT_UNMOUNTED:
      g_assert (!other);
      g_print ("%s: unmounted", child_str);
      break;
    case G_FILE_MONITOR_EVENT_MOVED_IN:
      g_print ("%s: moved in", child_str);
      if (other)
        g_print (" (from %s)", other_str);
      break;
    case G_FILE_MONITOR_EVENT_MOVED_OUT:
      g_print ("%s: moved out", child_str);
      if (other)
        g_print (" (to %s)", other_str);
      break;
    case G_FILE_MONITOR_EVENT_RENAMED:
      g_assert (other);
      g_print ("%s: renamed to %s\n", child_str, other_str);
      break;

    case G_FILE_MONITOR_EVENT_MOVED:
    default:
      g_assert_not_reached ();
    }

  g_free (child_str);
  g_free (other_str);
  g_print ("\n");
}

typedef enum
{
  WATCH_DIR,
  WATCH_FILE,
  WATCH_AUTO
} WatchType;

static gboolean
add_watch (const gchar       *cmdline,
           WatchType          watch_type,
           GFileMonitorFlags  flags,
           gboolean           connect_handler)
{
  GFileMonitor *monitor = NULL;
  GError *error = NULL;
  GFile *file;

  file = g_file_new_for_commandline_arg (cmdline);

  if (watch_type == WATCH_AUTO)
    {
      GFileInfo *info;
      guint32 type;

      info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error);
      if (!info)
        goto err;

      type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
      watch_type = (type == G_FILE_TYPE_DIRECTORY) ? WATCH_DIR : WATCH_FILE;
    }

  if (watch_type == WATCH_DIR)
    monitor = g_file_monitor_directory (file, flags, NULL, &error);
  else
    monitor = g_file_monitor (file, flags, NULL, &error);

  if (!monitor)
    goto err;

  if (connect_handler)
    g_signal_connect (monitor, "changed", G_CALLBACK (watch_callback), g_strdup (cmdline));

  monitor = NULL; /* leak */
  g_object_unref (file);

  return TRUE;

err:
  print_file_error (file, error->message);
  g_error_free (error);
  g_object_unref (file);

  return FALSE;
}

int
handle_monitor (int argc, gchar *argv[], gboolean do_help)
{
  GOptionContext *context;
  gchar *param;
  GError *error = NULL;
  GFileMonitorFlags flags;
  guint i;

  g_set_prgname ("gio monitor");

  /* 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,
    _("Monitor files or directories for changes."));
  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 (!watch_dirs && !watch_files && !watch_direct && !watch_silent && !watch_default)
    {
      show_help (context, _("No locations given"));
      g_option_context_free (context);
      return 1;
    }

  g_option_context_free (context);

  flags = (no_moves ? 0 : G_FILE_MONITOR_WATCH_MOVES) |
          (mounts ? G_FILE_MONITOR_WATCH_MOUNTS : 0);

  if (watch_dirs)
    {
      for (i = 0; watch_dirs[i]; i++)
        if (!add_watch (watch_dirs[i], WATCH_DIR, flags, TRUE))
          return 1;
    }

  if (watch_files)
    {
      for (i = 0; watch_files[i]; i++)
        if (!add_watch (watch_files[i], WATCH_FILE, flags, TRUE))
          return 1;
    }

  if (watch_direct)
    {
      for (i = 0; watch_direct[i]; i++)
        if (!add_watch (watch_direct[i], WATCH_FILE, flags | G_FILE_MONITOR_WATCH_HARD_LINKS, TRUE))
          return 1;
    }

  if (watch_silent)
    {
      for (i = 0; watch_silent[i]; i++)
        if (!add_watch (watch_silent[i], WATCH_FILE, flags | G_FILE_MONITOR_WATCH_HARD_LINKS, FALSE))
          return 1;
    }

  if (watch_default)
    {
      for (i = 0; watch_default[i]; i++)
        if (!add_watch (watch_default[i], WATCH_AUTO, flags, TRUE))
          return 1;
    }

  while (TRUE)
    g_main_context_iteration (NULL, TRUE);

  return 0;
}
