/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 * Copyright (C) 2008 Hans Breuer
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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: Alexander Larsson <alexl@redhat.com>
 *         David Zeuthen <davidz@redhat.com>
 *         Hans Breuer <hans@breuer.org>
 */

#include "config.h"

#include <string.h>
#define WIN32_MEAN_AND_LEAN
#define COBJMACROS
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>

/* At the moment of writing IExtractIconW interface in Mingw-w64
 * is missing IUnknown members in its vtable. Use our own
 * fixed declaration for now.
 */
#undef INTERFACE
#define INTERFACE IMyExtractIconW
DECLARE_INTERFACE_(IMyExtractIconW,IUnknown)
{
    /*** IUnknown methods ***/
    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;
    /*** IMyExtractIconW methods ***/
    STDMETHOD(GetIconLocation)(THIS_ UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, PUINT pwFlags) PURE;
    STDMETHOD(Extract)(THIS_ LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) PURE;
};
#undef INTERFACE

#if !defined(__cplusplus) || defined(CINTERFACE)
/*** IUnknown methods ***/
#define IMyExtractIconW_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IMyExtractIconW_AddRef(p)             (p)->lpVtbl->AddRef(p)
#define IMyExtractIconW_Release(p)            (p)->lpVtbl->Release(p)
/*** IMyExtractIconW methods ***/
#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->lpVtbl->GetIconLocation(p,a,b,c,d,e)
#define IMyExtractIconW_Extract(p,a,b,c,d,e)         (p)->lpVtbl->Extract(p,a,b,c,d,e)
#else
/*** IUnknown methods ***/
#define IMyExtractIconW_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
#define IMyExtractIconW_AddRef(p)             (p)->AddRef()
#define IMyExtractIconW_Release(p)            (p)->Release()
/*** IMyExtractIconW methods ***/
#define IMyExtractIconW_GetIconLocation(p,a,b,c,d,e) (p)->GetIconLocation(p,a,b,c,d,e)
#define IMyExtractIconW_Extract(p,a,b,c,d,e)         (p)->Extract(p,a,b,c,d,e)
#endif


#include <glib.h>
#include "gwin32volumemonitor.h"
#include "gwin32mount.h"
#include "gmount.h"
#include "gfile.h"
#include "gmountprivate.h"
#include "gvolumemonitor.h"
#include "gthemedicon.h"
#include "glibintl.h"


struct _GWin32Mount {
  GObject parent;

  GVolumeMonitor   *volume_monitor;

  GWin32Volume      *volume; /* owned by volume monitor */
  int   drive_type;

  /* why does all this stuff need to be duplicated? It is in volume already! */
  char *name;
  GIcon *icon;
  GIcon *symbolic_icon;
  char *mount_path;

  gboolean can_eject;
};

static void g_win32_mount_mount_iface_init (GMountIface *iface);

#define g_win32_mount_get_type _g_win32_mount_get_type
G_DEFINE_TYPE_WITH_CODE (GWin32Mount, g_win32_mount, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
						g_win32_mount_mount_iface_init))


static void
g_win32_mount_finalize (GObject *object)
{
  GWin32Mount *mount;
  
  mount = G_WIN32_MOUNT (object);

  if (mount->volume_monitor != NULL)
    g_object_unref (mount->volume_monitor);
#if 0
  if (mount->volume)
    _g_win32_volume_unset_mount (mount->volume, mount);
#endif
  /* TODO: g_warn_if_fail (volume->volume == NULL); */

  if (mount->icon != NULL)
    g_object_unref (mount->icon);
  if (mount->symbolic_icon != NULL)
    g_object_unref (mount->symbolic_icon);

  g_free (mount->name);
  g_free (mount->mount_path);
  
  if (G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize)
    (*G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize) (object);
}

static void
g_win32_mount_class_init (GWin32MountClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = g_win32_mount_finalize;
}

static void
g_win32_mount_init (GWin32Mount *win32_mount)
{
}

/* wdrive doesn't need to end with a path separator.
   wdrive must use backslashes as path separators, not slashes.
   IShellFolder::ParseDisplayName() takes non-const string as input,
   so wdrive can't be a const string.
   Returns the name on success (free with g_free),
   NULL otherwise.
 */
static gchar *
get_mount_display_name (gunichar2 *wdrive)
{
  IShellFolder *desktop;
  PIDLIST_RELATIVE volume;
  STRRET volume_name;
  gchar *result = NULL;

  /* Get the desktop folder object reference */
  if (!SUCCEEDED (SHGetDesktopFolder (&desktop)))
    return result;

  if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, wdrive, NULL, &volume, NULL)))
    {
      volume_name.uType = STRRET_WSTR;

      if (SUCCEEDED (IShellFolder_GetDisplayNameOf (desktop, volume, SHGDN_FORADDRESSBAR, &volume_name)))
        {
          wchar_t *volume_name_wchar;

          if (SUCCEEDED (StrRetToStrW (&volume_name, volume, &volume_name_wchar)))
            {
              result = g_utf16_to_utf8 (volume_name_wchar, -1, NULL, NULL, NULL);
              CoTaskMemFree (volume_name_wchar);
            }
        }
      CoTaskMemFree (volume);
    }

  IShellFolder_Release (desktop);

  return result;
}

static gchar *
_win32_get_displayname (const char *drive)
{
  gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);
  gchar *name = get_mount_display_name (wdrive);

  g_free (wdrive);
  return name ? name : g_strdup (drive);
}

/*
 * _g_win32_mount_new:
 * @volume_monitor: a #GVolumeMonitor.
 * @path: a win32 path.
 * @volume: usually NULL
 * 
 * Returns: a #GWin32Mount for the given win32 path.
 **/
GWin32Mount *
_g_win32_mount_new (GVolumeMonitor  *volume_monitor,
                    const char      *path,
                    GWin32Volume    *volume)
{
  GWin32Mount *mount;
  const gchar *drive = path; //fixme
  WCHAR *drive_utf16;

  drive_utf16 = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);

#if 0  
  /* No volume for mount: Ignore internal things */
  if (volume == NULL && !g_win32_mount_guess_should_display (mount_entry))
    return NULL;
#endif

  mount = g_object_new (G_TYPE_WIN32_MOUNT, NULL);
  mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL;
  mount->mount_path = g_strdup (path);
  mount->drive_type = GetDriveTypeW (drive_utf16);
  mount->can_eject = FALSE; /* TODO */
  mount->name = _win32_get_displayname (drive);

  /* need to do this last */
  mount->volume = volume;
#if 0
  if (volume != NULL)
    _g_win32_volume_set_mount (volume, mount);
#endif

  g_free (drive_utf16);

  return mount;
}

void
_g_win32_mount_unmounted (GWin32Mount *mount)
{
  if (mount->volume != NULL)
    {
#if 0
      _g_win32_volume_unset_mount (mount->volume, mount);
#endif
      mount->volume = NULL;
      g_signal_emit_by_name (mount, "changed");
      /* there's really no need to emit mount_changed on the volume monitor 
       * as we're going to be deleted.. */
    }
}

void
_g_win32_mount_unset_volume (GWin32Mount  *mount,
			     GWin32Volume *volume)
{
  if (mount->volume == volume)
    {
      mount->volume = NULL;
      /* TODO: Emit changed in idle to avoid locking issues */
      g_signal_emit_by_name (mount, "changed");
      if (mount->volume_monitor != NULL)
        g_signal_emit_by_name (mount->volume_monitor, "mount-changed", mount);
    }
}

static GFile *
g_win32_mount_get_root (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);

  return g_file_new_for_path (win32_mount->mount_path);
}

static const char *
_win32_drive_type_to_icon (int type, gboolean use_symbolic)
{
  switch (type)
  {
  case DRIVE_REMOVABLE : return use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media";
  case DRIVE_FIXED : return use_symbolic ? "drive-harddisk-symbolic" : "drive-harddisk";
  case DRIVE_REMOTE : return use_symbolic ? "folder-remote-symbolic" : "folder-remote";
  case DRIVE_CDROM : return use_symbolic ? "drive-optical-symbolic" : "drive-optical";
  default : return use_symbolic ? "folder-symbolic" : "folder";
  }
}

/* mount_path doesn't need to end with a path separator.
   mount_path must use backslashes as path separators, not slashes.
   IShellFolder::ParseDisplayName() takes non-const string as input,
   so mount_path can't be a const string.
   result_name and result_index must not be NULL.
   Returns TRUE when result_name is set (free with g_free),
   FALSE otherwise.
 */
static gboolean
get_icon_name_index (wchar_t  *mount_path,
                     wchar_t **result_name,
                     int      *result_index)
{
  IShellFolder *desktop;
  PIDLIST_RELATIVE volume;
  IShellFolder *volume_parent;
  PCUITEMID_CHILD volume_relative;
  IMyExtractIconW *eicon;
  int icon_index;
  UINT icon_flags;
  wchar_t *name_buffer;
  gsize name_buffer_size;
  gsize arbitrary_reasonable_limit = 5000;
  gboolean result = FALSE;

  *result_name = NULL;

  /* Get the desktop folder object reference */
  if (!SUCCEEDED (SHGetDesktopFolder (&desktop)))
    return FALSE;

  /* Construct the volume IDList relative to desktop */
  if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, mount_path, NULL, &volume, NULL)))
    {
      /* Get the parent of the volume (transfer-full) and the IDList relative to parent (transfer-none) */
      if (SUCCEEDED (SHBindToParent (volume, &IID_IShellFolder, (void **) &volume_parent, &volume_relative)))
        {
          /* Get a reference to IExtractIcon object for the volume */
          if (SUCCEEDED (IShellFolder_GetUIObjectOf (volume_parent, NULL, 1, (LPCITEMIDLIST *) &volume_relative, &IID_IExtractIconW, NULL, (void **) &eicon)))
            {
              gboolean keep_going = TRUE;
              name_buffer = NULL;
              name_buffer_size = MAX_PATH / 2;
              while (keep_going)
                {
                  name_buffer_size *= 2;
                  name_buffer = g_renew (wchar_t, name_buffer, name_buffer_size);
                  name_buffer[name_buffer_size - 1] = 0x1; /* sentinel */
                  keep_going = FALSE;

                  /* Try to get the icon location */
                  if (SUCCEEDED (IMyExtractIconW_GetIconLocation (eicon, GIL_FORSHELL, name_buffer, name_buffer_size, &icon_index, &icon_flags)))
                    {
                      if (name_buffer[name_buffer_size - 1] != 0x1)
                        {
                          if (name_buffer_size < arbitrary_reasonable_limit)
                            {
                              /* Buffer was too small, keep going */
                              keep_going = TRUE;
                              continue;
                            }
                          /* Else stop trying */
                        }
                      /* name_buffer might not contain a name */
                      else if ((icon_flags & GIL_NOTFILENAME) != GIL_NOTFILENAME)
                        {
                          *result_name = g_steal_pointer (&name_buffer);
                          *result_index = icon_index;
                          result = TRUE;
                        }
                    }
                }

              g_free (name_buffer);
              IMyExtractIconW_Release (eicon);
            }
          IShellFolder_Release (volume_parent);
        }
      CoTaskMemFree (volume);
    }

  IShellFolder_Release (desktop);

  return result;
}

static GIcon *
g_win32_mount_get_icon (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);

  g_return_val_if_fail (win32_mount->mount_path != NULL, NULL);

  /* lazy creation */
  if (!win32_mount->icon)
    {
      wchar_t *icon_path;
      int icon_index;
      wchar_t *p;
      wchar_t *wfn = g_utf8_to_utf16 (win32_mount->mount_path, -1, NULL, NULL, NULL);

      for (p = wfn; p != NULL && *p != 0; p++)
        if (*p == L'/')
          *p = L'\\';

      if (get_icon_name_index (wfn, &icon_path, &icon_index))
        {
	  gchar *id = g_strdup_printf ("%S,%i", icon_path, icon_index);
	  g_free (icon_path);
	  win32_mount->icon = g_themed_icon_new (id);
	  g_free (id);
	}
      else
        {
          win32_mount->icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, FALSE));
	}

      g_free (wfn);
    }

  return g_object_ref (win32_mount->icon);
}

static GIcon *
g_win32_mount_get_symbolic_icon (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);

  g_return_val_if_fail (win32_mount->mount_path != NULL, NULL);

  /* lazy creation */
  if (!win32_mount->symbolic_icon)
    {
      win32_mount->symbolic_icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, TRUE));
    }

  return g_object_ref (win32_mount->symbolic_icon);
}

static char *
g_win32_mount_get_uuid (GMount *mount)
{
  return NULL;
}

static char *
g_win32_mount_get_name (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
  
  return g_strdup (win32_mount->name);
}

static GDrive *
g_win32_mount_get_drive (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);

  if (win32_mount->volume != NULL)
    return g_volume_get_drive (G_VOLUME (win32_mount->volume));

  return NULL;
}

static GVolume *
g_win32_mount_get_volume (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);

  if (win32_mount->volume)
    return G_VOLUME (g_object_ref (win32_mount->volume));
  
  return NULL;
}

static gboolean
g_win32_mount_can_unmount (GMount *mount)
{
  return FALSE;
}

static gboolean
g_win32_mount_can_eject (GMount *mount)
{
  GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
  return win32_mount->can_eject;
}


typedef struct {
  GWin32Mount *win32_mount;
  GAsyncReadyCallback callback;
  gpointer user_data;
  GCancellable *cancellable;
  int error_fd;
  GIOChannel *error_channel;
  guint error_channel_source_id;
  GString *error_string;
} UnmountEjectOp;

static void
g_win32_mount_unmount (GMount              *mount,
		       GMountUnmountFlags   flags,
		       GCancellable        *cancellable,
		       GAsyncReadyCallback  callback,
		       gpointer             user_data)
{
}

static gboolean
g_win32_mount_unmount_finish (GMount        *mount,
			      GAsyncResult  *result,
			      GError       **error)
{
  return FALSE;
}

static void
g_win32_mount_eject (GMount              *mount,
		     GMountUnmountFlags   flags,
		     GCancellable        *cancellable,
		     GAsyncReadyCallback  callback,
		     gpointer             user_data)
{
}

static gboolean
g_win32_mount_eject_finish (GMount        *mount,
			    GAsyncResult  *result,
			    GError       **error)
{
  return FALSE;
}

static void
g_win32_mount_mount_iface_init (GMountIface *iface)
{
  iface->get_root = g_win32_mount_get_root;
  iface->get_name = g_win32_mount_get_name;
  iface->get_icon = g_win32_mount_get_icon;
  iface->get_symbolic_icon = g_win32_mount_get_symbolic_icon;
  iface->get_uuid = g_win32_mount_get_uuid;
  iface->get_drive = g_win32_mount_get_drive;
  iface->get_volume = g_win32_mount_get_volume;
  iface->can_unmount = g_win32_mount_can_unmount;
  iface->can_eject = g_win32_mount_can_eject;
  iface->unmount = g_win32_mount_unmount;
  iface->unmount_finish = g_win32_mount_unmount_finish;
  iface->eject = g_win32_mount_eject;
  iface->eject_finish = g_win32_mount_eject_finish;
}
