/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2006-2007 Red Hat, Inc.
 * Copyright (C) 2015 Chun-wei Fan
 *
 * 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: Vlad Grecescu <b100dian@gmail.com>
 * Author: Chun-wei Fan <fanc999@yahoo.com.tw>
 *
 */

#include "config.h"

#include "gwin32fsmonitorutils.h"
#include "gio/gfile.h"

#include <windows.h>

#define MAX_PATH_LONG 32767 /* Support Paths longer than MAX_PATH (260) characters */

static gboolean
g_win32_fs_monitor_handle_event (GWin32FSMonitorPrivate   *monitor,
                                 const gchar              *filename,
                                 PFILE_NOTIFY_INFORMATION  pfni)
{
  GFileMonitorEvent fme;
  PFILE_NOTIFY_INFORMATION pfni_next;
  WIN32_FILE_ATTRIBUTE_DATA attrib_data = {0, };
  gchar *renamed_file = NULL;

  switch (pfni->Action)
    {
    case FILE_ACTION_ADDED:
      fme = G_FILE_MONITOR_EVENT_CREATED;
      break;

    case FILE_ACTION_REMOVED:
      fme = G_FILE_MONITOR_EVENT_DELETED;
      break;

    case FILE_ACTION_MODIFIED:
      {
        gboolean success_attribs = GetFileAttributesExW (monitor->wfullpath_with_long_prefix,
                                                         GetFileExInfoStandard,
                                                         &attrib_data);

        if (monitor->file_attribs != INVALID_FILE_ATTRIBUTES &&
            success_attribs &&
            attrib_data.dwFileAttributes != monitor->file_attribs)
          fme = G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;
        else
          fme = G_FILE_MONITOR_EVENT_CHANGED;

        monitor->file_attribs = attrib_data.dwFileAttributes;
      }
      break;

    case FILE_ACTION_RENAMED_OLD_NAME:
      if (pfni->NextEntryOffset != 0)
        {
          /* If the file was renamed in the same directory, we would get a
           * FILE_ACTION_RENAMED_NEW_NAME action in the next FILE_NOTIFY_INFORMATION
           * structure.
           */
          glong file_name_len = 0;

          pfni_next = (PFILE_NOTIFY_INFORMATION) ((BYTE*)pfni + pfni->NextEntryOffset);
          renamed_file = g_utf16_to_utf8 (pfni_next->FileName, pfni_next->FileNameLength / sizeof(WCHAR), NULL, &file_name_len, NULL);
          if (pfni_next->Action == FILE_ACTION_RENAMED_NEW_NAME)
           fme = G_FILE_MONITOR_EVENT_RENAMED;
          else
           fme = G_FILE_MONITOR_EVENT_MOVED_OUT;
        }
      else
        fme = G_FILE_MONITOR_EVENT_MOVED_OUT;
      break;

    case FILE_ACTION_RENAMED_NEW_NAME:
      if (monitor->pfni_prev != NULL &&
          monitor->pfni_prev->Action == FILE_ACTION_RENAMED_OLD_NAME)
        {
          /* don't bother sending events, was already sent (rename) */
          fme = -1;
        }
      else
        fme = G_FILE_MONITOR_EVENT_MOVED_IN;
      break;

    default:
      /* The possible Windows actions are all above, so shouldn't get here */
      g_assert_not_reached ();
      break;
    }

  if (fme != -1)
    return g_file_monitor_source_handle_event (monitor->fms,
                                               fme,
                                               filename,
                                               renamed_file,
                                               NULL,
                                               g_get_monotonic_time ());
  else
    return FALSE;
}


static void CALLBACK
g_win32_fs_monitor_callback (DWORD        error,
                             DWORD        nBytes,
                             LPOVERLAPPED lpOverlapped)
{
  gulong offset;
  PFILE_NOTIFY_INFORMATION pfile_notify_walker;
  GWin32FSMonitorPrivate *monitor = (GWin32FSMonitorPrivate *) lpOverlapped;

  DWORD notify_filter = monitor->isfile ?
                        (FILE_NOTIFY_CHANGE_FILE_NAME |
                         FILE_NOTIFY_CHANGE_ATTRIBUTES |
                         FILE_NOTIFY_CHANGE_SIZE) :
                        (FILE_NOTIFY_CHANGE_FILE_NAME |
                         FILE_NOTIFY_CHANGE_DIR_NAME |
                         FILE_NOTIFY_CHANGE_ATTRIBUTES |
                         FILE_NOTIFY_CHANGE_SIZE);

  /* If monitor->self is NULL the GWin32FileMonitor object has been destroyed. */
  if (monitor->self == NULL ||
      g_file_monitor_is_cancelled (monitor->self) ||
      monitor->file_notify_buffer == NULL)
    {
      g_free (monitor->file_notify_buffer);
      g_free (monitor);
      return;
    }

  offset = 0;

  do
    {
      pfile_notify_walker = (PFILE_NOTIFY_INFORMATION)((BYTE *)monitor->file_notify_buffer + offset);
      if (pfile_notify_walker->Action > 0)
        {
          glong file_name_len;
          gchar *changed_file;

          changed_file = g_utf16_to_utf8 (pfile_notify_walker->FileName,
                                          pfile_notify_walker->FileNameLength / sizeof(WCHAR),
                                          NULL, &file_name_len, NULL);

          if (monitor->isfile)
            {
              gint long_filename_length = wcslen (monitor->wfilename_long);
              gint short_filename_length = wcslen (monitor->wfilename_short);
              enum GWin32FileMonitorFileAlias alias_state;

              /* If monitoring a file, check that the changed file
              * in the directory matches the file that is to be monitored
              * We need to check both the long and short file names for the same file.
              *
              * We need to send in the name of the monitored file, not its long (or short) variant,
              * if they exist.
              */

              if (_wcsnicmp (pfile_notify_walker->FileName,
                             monitor->wfilename_long,
                             long_filename_length) == 0)
                {
                  if (_wcsnicmp (pfile_notify_walker->FileName,
                                 monitor->wfilename_short,
                                 short_filename_length) == 0)
                    {
                      alias_state = G_WIN32_FILE_MONITOR_NO_ALIAS;
                    }
                  else
                    alias_state = G_WIN32_FILE_MONITOR_LONG_FILENAME;
                }
              else if (_wcsnicmp (pfile_notify_walker->FileName,
                                  monitor->wfilename_short,
                                  short_filename_length) == 0)
                {
                  alias_state = G_WIN32_FILE_MONITOR_SHORT_FILENAME;
                }
              else
                alias_state = G_WIN32_FILE_MONITOR_NO_MATCH_FOUND;

              if (alias_state != G_WIN32_FILE_MONITOR_NO_MATCH_FOUND)
                {
                  wchar_t *monitored_file_w;
                  gchar *monitored_file;

                  switch (alias_state)
                    {
                    case G_WIN32_FILE_MONITOR_NO_ALIAS:
                      monitored_file = g_strdup (changed_file);
                      break;
                    case G_WIN32_FILE_MONITOR_LONG_FILENAME:
                    case G_WIN32_FILE_MONITOR_SHORT_FILENAME:
                      monitored_file_w = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\');
                      monitored_file = g_utf16_to_utf8 (monitored_file_w + 1, -1, NULL, NULL, NULL);
                      break;
                    default:
                      g_assert_not_reached ();
                      break;
                    }

                  g_win32_fs_monitor_handle_event (monitor, monitored_file, pfile_notify_walker);
                  g_free (monitored_file);
                }
            }
          else
            g_win32_fs_monitor_handle_event (monitor, changed_file, pfile_notify_walker);

          g_free (changed_file);
        }

      monitor->pfni_prev = pfile_notify_walker;
      offset += pfile_notify_walker->NextEntryOffset;
    }
  while (pfile_notify_walker->NextEntryOffset);

  ReadDirectoryChangesW (monitor->hDirectory,
                         monitor->file_notify_buffer,
                         monitor->buffer_allocated_bytes,
                         FALSE,
                         notify_filter,
                         &monitor->buffer_filled_bytes,
                         &monitor->overlapped,
                         g_win32_fs_monitor_callback);
}

void
g_win32_fs_monitor_init (GWin32FSMonitorPrivate *monitor,
                         const gchar *dirname,
                         const gchar *filename,
                         gboolean isfile)
{
  wchar_t *wdirname_with_long_prefix = NULL;
  const gchar LONGPFX[] = "\\\\?\\";
  gchar *fullpath_with_long_prefix, *dirname_with_long_prefix;
  DWORD notify_filter = isfile ?
                        (FILE_NOTIFY_CHANGE_FILE_NAME |
                         FILE_NOTIFY_CHANGE_ATTRIBUTES |
                         FILE_NOTIFY_CHANGE_SIZE) :
                        (FILE_NOTIFY_CHANGE_FILE_NAME |
                         FILE_NOTIFY_CHANGE_DIR_NAME |
                         FILE_NOTIFY_CHANGE_ATTRIBUTES |
                         FILE_NOTIFY_CHANGE_SIZE);

  gboolean success_attribs;
  WIN32_FILE_ATTRIBUTE_DATA attrib_data = {0, };


  if (dirname != NULL)
    {
      dirname_with_long_prefix = g_strconcat (LONGPFX, dirname, NULL);
      wdirname_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL);

      if (isfile)
        {
          gchar *fullpath;
          wchar_t wlongname[MAX_PATH_LONG];
          wchar_t wshortname[MAX_PATH_LONG];
          wchar_t *wfullpath, *wbasename_long, *wbasename_short;

          fullpath = g_build_filename (dirname, filename, NULL);
          fullpath_with_long_prefix = g_strconcat (LONGPFX, fullpath, NULL);

          wfullpath = g_utf8_to_utf16 (fullpath, -1, NULL, NULL, NULL);

          monitor->wfullpath_with_long_prefix =
            g_utf8_to_utf16 (fullpath_with_long_prefix, -1, NULL, NULL, NULL);

          /* ReadDirectoryChangesW() can return the normal filename or the
           * "8.3" format filename, so we need to keep track of both these names
           * so that we can check against them later when it returns
           */
          if (GetLongPathNameW (monitor->wfullpath_with_long_prefix, wlongname, MAX_PATH_LONG) == 0)
            {
              wbasename_long = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\');
              monitor->wfilename_long = wbasename_long != NULL ?
                                        wcsdup (wbasename_long + 1) :
                                        wcsdup (wfullpath);
            }
          else
            {
              wbasename_long = wcsrchr (wlongname, L'\\');
              monitor->wfilename_long = wbasename_long != NULL ?
                                        wcsdup (wbasename_long + 1) :
                                        wcsdup (wlongname);

            }

          if (GetShortPathNameW (monitor->wfullpath_with_long_prefix, wshortname, MAX_PATH_LONG) == 0)
            {
              wbasename_short = wcsrchr (monitor->wfullpath_with_long_prefix, L'\\');
              monitor->wfilename_short = wbasename_short != NULL ?
                                         wcsdup (wbasename_short + 1) :
                                         wcsdup (wfullpath);
            }
          else
            {
              wbasename_short = wcsrchr (wshortname, L'\\');
              monitor->wfilename_short = wbasename_short != NULL ?
                                         wcsdup (wbasename_short + 1) :
                                         wcsdup (wshortname);
            }

          g_free (fullpath);
        }
      else
        {
          monitor->wfilename_short = NULL;
          monitor->wfilename_long = NULL;
          monitor->wfullpath_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL);
        }

      monitor->isfile = isfile;
    }
  else
    {
      dirname_with_long_prefix = g_strconcat (LONGPFX, filename, NULL);
      monitor->wfullpath_with_long_prefix = g_utf8_to_utf16 (dirname_with_long_prefix, -1, NULL, NULL, NULL);
      monitor->wfilename_long = NULL;
      monitor->wfilename_short = NULL;
      monitor->isfile = FALSE;
    }

  success_attribs = GetFileAttributesExW (monitor->wfullpath_with_long_prefix,
                                          GetFileExInfoStandard,
                                          &attrib_data);
  if (success_attribs)
    monitor->file_attribs = attrib_data.dwFileAttributes; /* Store up original attributes */
  else
    monitor->file_attribs = INVALID_FILE_ATTRIBUTES;
  monitor->pfni_prev = NULL;
  monitor->hDirectory = CreateFileW (wdirname_with_long_prefix != NULL ? wdirname_with_long_prefix : monitor->wfullpath_with_long_prefix,
                                     FILE_LIST_DIRECTORY,
                                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                                     NULL,
                                     OPEN_EXISTING,
                                     FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                                     NULL);

  g_free (wdirname_with_long_prefix);
  g_free (dirname_with_long_prefix);

  if (monitor->hDirectory != INVALID_HANDLE_VALUE)
    {
      ReadDirectoryChangesW (monitor->hDirectory,
                             monitor->file_notify_buffer,
                             monitor->buffer_allocated_bytes,
                             FALSE,
                             notify_filter,
                             &monitor->buffer_filled_bytes,
                             &monitor->overlapped,
                             g_win32_fs_monitor_callback);
    }
}

GWin32FSMonitorPrivate *
g_win32_fs_monitor_create (gboolean isfile)
{
  GWin32FSMonitorPrivate *monitor = g_new0 (GWin32FSMonitorPrivate, 1);

  monitor->buffer_allocated_bytes = 32784;
  monitor->file_notify_buffer = g_new0 (FILE_NOTIFY_INFORMATION, monitor->buffer_allocated_bytes);

  return monitor;
}

void
g_win32_fs_monitor_finalize (GWin32FSMonitorPrivate *monitor)
{
  g_free (monitor->wfullpath_with_long_prefix);
  g_free (monitor->wfilename_long);
  g_free (monitor->wfilename_short);

  if (monitor->hDirectory == INVALID_HANDLE_VALUE)
    {
      /* If we don't have a directory handle we can free
       * monitor->file_notify_buffer and monitor here. The
       * callback won't be called obviously any more (and presumably
       * never has been called).
       */
      g_free (monitor->file_notify_buffer);
      monitor->file_notify_buffer = NULL;
      g_free (monitor);
    }
  else
    {
      /* If we have a directory handle, the OVERLAPPED struct is
       * passed once more to the callback as a result of the
       * CloseHandle() done in the cancel method, so monitor has to
       * be kept around. The GWin32DirectoryMonitor object is
       * disappearing, so can't leave a pointer to it in
       * monitor->self.
       */
      monitor->self = NULL;
    }
}

void
g_win32_fs_monitor_close_handle (GWin32FSMonitorPrivate *monitor)
{
  /* This triggers a last callback() with nBytes==0. */

  /* Actually I am not so sure about that, it seems to trigger a last
   * callback correctly, but the way to recognize that it is the final
   * one is not to check for nBytes==0, I think that was a
   * misunderstanding.
   */
  if (monitor->hDirectory != INVALID_HANDLE_VALUE)
    CloseHandle (monitor->hDirectory);
}
