/*
 * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "kshelpers.h"

/* This plugin is from the era of Windows XP and uses APIs that have been
 * deprecated since then. Let's pretend we're Windows XP too so that Windows
 * lets us use that deprecated API. */
#undef NTDDI_VERSION
#undef _WIN32_WINNT
#define NTDDI_VERSION NTDDI_WINXP
#define _WIN32_WINNT _WIN32_WINNT_WINXP

#include <ksmedia.h>
#include <setupapi.h>
#include <gst/gst.h>

GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
#define GST_CAT_DEFAULT gst_ks_debug

#ifndef STATIC_KSPROPSETID_Wave_Queued
#define STATIC_KSPROPSETID_Wave_Queued \
    0x16a15b10L, 0x16f0, 0x11d0, { 0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 }
DEFINE_GUIDSTRUCT ("16a15b10-16f0-11d0-a195-0020afd156e4",
    KSPROPSETID_Wave_Queued);
#endif

gboolean
ks_is_valid_handle (HANDLE h)
{
  return (h != INVALID_HANDLE_VALUE && h != NULL);
}

GList *
ks_enumerate_devices (const GUID * devtype, const GUID * direction_category)
{
  GList *result = NULL;
  HDEVINFO devinfo;
  gint i;

  devinfo = SetupDiGetClassDevsW (devtype, NULL, NULL,
      DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
  if (!ks_is_valid_handle (devinfo))
    return NULL;                /* no devices */

  for (i = 0;; i++) {
    BOOL success;
    SP_DEVICE_INTERFACE_DATA if_data = { 0, };
    SP_DEVICE_INTERFACE_DATA if_alias_data = { 0, };
    SP_DEVICE_INTERFACE_DETAIL_DATA_W *if_detail_data;
    DWORD if_detail_data_size;
    SP_DEVINFO_DATA devinfo_data = { 0, };
    DWORD req_size;

    if_data.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

    success = SetupDiEnumDeviceInterfaces (devinfo, NULL, devtype, i, &if_data);
    if (!success)               /* all devices enumerated? */
      break;

    if_alias_data.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
    success =
        SetupDiGetDeviceInterfaceAlias (devinfo, &if_data, direction_category,
        &if_alias_data);
    if (!success)
      continue;

    if_detail_data_size = (MAX_PATH - 1) * sizeof (gunichar2);
    if_detail_data = g_malloc0 (if_detail_data_size);
    if_detail_data->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA_W);

    devinfo_data.cbSize = sizeof (SP_DEVINFO_DATA);

    success = SetupDiGetDeviceInterfaceDetailW (devinfo, &if_data,
        if_detail_data, if_detail_data_size, &req_size, &devinfo_data);
    if (success) {
      KsDeviceEntry *entry;
      WCHAR buf[512];

      entry = g_new0 (KsDeviceEntry, 1);
      entry->index = i;
      entry->path =
          g_utf16_to_utf8 (if_detail_data->DevicePath, -1, NULL, NULL, NULL);

      if (SetupDiGetDeviceRegistryPropertyW (devinfo, &devinfo_data,
              SPDRP_FRIENDLYNAME, NULL, (BYTE *) buf, sizeof (buf), NULL)) {
        entry->name = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
      }

      if (entry->name == NULL) {
        if (SetupDiGetDeviceRegistryPropertyW (devinfo, &devinfo_data,
                SPDRP_DEVICEDESC, NULL, (BYTE *) buf, sizeof (buf), NULL)) {
          entry->name = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
        }
      }

      if (entry->name != NULL)
        result = g_list_prepend (result, entry);
      else
        ks_device_entry_free (entry);
    }

    g_free (if_detail_data);
  }

  SetupDiDestroyDeviceInfoList (devinfo);

  return g_list_reverse (result);
}

void
ks_device_entry_free (KsDeviceEntry * entry)
{
  if (entry == NULL)
    return;

  g_free (entry->path);
  g_free (entry->name);

  g_free (entry);
}

void
ks_device_list_free (GList * devices)
{
  GList *cur;

  for (cur = devices; cur != NULL; cur = cur->next)
    ks_device_entry_free (cur->data);

  g_list_free (devices);
}

static gboolean
ks_sync_device_io_control (HANDLE device, gulong io_control_code,
    gpointer in_buffer, gulong in_buffer_size, gpointer out_buffer,
    gulong out_buffer_size, gulong * bytes_returned, gulong * error)
{
  OVERLAPPED overlapped = { 0, };
  BOOL success;

  overlapped.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);

  success = DeviceIoControl (device, io_control_code, in_buffer,
      in_buffer_size, out_buffer, out_buffer_size, bytes_returned, &overlapped);
  if (!success) {
    DWORD err;

    if ((err = GetLastError ()) == ERROR_IO_PENDING) {
      success = GetOverlappedResult (device, &overlapped, bytes_returned, TRUE);
      if (!success)
        err = GetLastError ();
    }

    if (error != NULL)
      *error = err;
  }

  CloseHandle (overlapped.hEvent);

  return success ? TRUE : FALSE;
}

gboolean
ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id,
    GUID prop_set, gulong prop_id, gpointer value, gulong value_size,
    gulong * error)
{
  KSP_PIN prop;
  DWORD bytes_returned = 0;

  memset (&prop, 0, sizeof (KSP_PIN));

  prop.PinId = pin_id;
  prop.Property.Set = prop_set;
  prop.Property.Id = prop_id;
  prop.Property.Flags = KSPROPERTY_TYPE_GET;

  return ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY, &prop,
      sizeof (prop), value, value_size, &bytes_returned, error);
}

gboolean
ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id,
    GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items, gulong * error)
{
  KSP_PIN prop;
  DWORD items_size = 0, bytes_written = 0;
  gulong err;
  gboolean ret;

  memset (&prop, 0, sizeof (KSP_PIN));
  *items = NULL;

  prop.PinId = pin_id;
  prop.Property.Set = prop_set;
  prop.Property.Id = prop_id;
  prop.Property.Flags = KSPROPERTY_TYPE_GET;

  ret = ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY,
      &prop.Property, sizeof (prop), NULL, 0, &items_size, &err);
  if (!ret && err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
    goto ioctl_failed;

  *items = g_malloc0 (items_size);

  ret = ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY, &prop,
      sizeof (prop), *items, items_size, &bytes_written, &err);
  if (!ret)
    goto ioctl_failed;

  return ret;

ioctl_failed:
  if (error != NULL)
    *error = err;

  g_free (*items);
  *items = NULL;

  return FALSE;
}

gboolean
ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id,
    gulong prop_flags, gpointer * value, gulong * value_size, gulong * error)
{
  KSPROPERTY prop;
  DWORD req_value_size = 0, bytes_written = 0;
  gulong err;
  gboolean ret;

  memset (&prop, 0, sizeof (KSPROPERTY));
  *value = NULL;

  prop.Set = prop_set;
  prop.Id = prop_id;
  prop.Flags = prop_flags;

  if (value_size == NULL || *value_size == 0) {
    ret = ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY,
        &prop, sizeof (prop), NULL, 0, &req_value_size, &err);
    if (!ret && err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
      goto ioctl_failed;
  } else {
    req_value_size = *value_size;
  }

  *value = g_malloc0 (req_value_size);

  ret = ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY, &prop,
      sizeof (prop), *value, req_value_size, &bytes_written, &err);
  if (!ret)
    goto ioctl_failed;

  if (value_size != NULL)
    *value_size = bytes_written;

  return ret;

ioctl_failed:
  if (error != NULL)
    *error = err;

  g_free (*value);
  *value = NULL;

  if (value_size != NULL)
    *value_size = 0;

  return FALSE;
}

gboolean
ks_object_get_property (HANDLE handle, GUID prop_set, gulong prop_id,
    gpointer * value, gulong * value_size, gulong * error)
{
  return ks_object_query_property (handle, prop_set, prop_id,
      KSPROPERTY_TYPE_GET, value, value_size, error);
}

gboolean
ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id,
    gpointer value, gulong value_size, gulong * error)
{
  KSPROPERTY prop;
  DWORD bytes_returned;

  memset (&prop, 0, sizeof (KSPROPERTY));
  prop.Set = prop_set;
  prop.Id = prop_id;
  prop.Flags = KSPROPERTY_TYPE_SET;

  return ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY, &prop,
      sizeof (prop), value, value_size, &bytes_returned, error);
}

gboolean
ks_object_get_supported_property_sets (HANDLE handle, GUID ** propsets,
    gulong * len)
{
  gulong size = 0;
  gulong error;

  *propsets = NULL;
  *len = 0;

  if (ks_object_query_property (handle, GUID_NULL, 0,
          KSPROPERTY_TYPE_SETSUPPORT, (void *) propsets, &size, &error)) {
    if (size % sizeof (GUID) == 0) {
      *len = size / sizeof (GUID);
      return TRUE;
    }
  }

  g_free (*propsets);
  *propsets = NULL;
  *len = 0;
  return FALSE;
}

gboolean
ks_object_set_connection_state (HANDLE handle, KSSTATE state, gulong * error)
{
  return ks_object_set_property (handle, KSPROPSETID_Connection,
      KSPROPERTY_CONNECTION_STATE, &state, sizeof (state), error);
}

gchar *
ks_guid_to_string (const GUID * guid)
{
  return g_strdup_printf ("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
      (guint) guid->Data1, (guint) guid->Data2, (guint) guid->Data3,
      (guint) guid->Data4[0], (guint) guid->Data4[1], (guint) guid->Data4[2],
      (guint) guid->Data4[3], (guint) guid->Data4[4], (guint) guid->Data4[5],
      (guint) guid->Data4[6], (guint) guid->Data4[7]);
}

const gchar *
ks_state_to_string (KSSTATE state)
{
  switch (state) {
    case KSSTATE_STOP:
      return "KSSTATE_STOP";
    case KSSTATE_ACQUIRE:
      return "KSSTATE_ACQUIRE";
    case KSSTATE_PAUSE:
      return "KSSTATE_PAUSE";
    case KSSTATE_RUN:
      return "KSSTATE_RUN";
    default:
      g_assert_not_reached ();
  }

  return "UNKNOWN";
}

#define CHECK_OPTIONS_FLAG(flag) \
  if (flags & KSSTREAM_HEADER_OPTIONSF_##flag)\
  {\
    if (str->len > 0)\
      g_string_append (str, "|");\
    g_string_append (str, G_STRINGIFY (flag));\
    flags &= ~KSSTREAM_HEADER_OPTIONSF_##flag;\
  }

gchar *
ks_options_flags_to_string (gulong flags)
{
  gchar *ret;
  GString *str;

  str = g_string_sized_new (128);

  CHECK_OPTIONS_FLAG (SPLICEPOINT);
  CHECK_OPTIONS_FLAG (PREROLL);
  CHECK_OPTIONS_FLAG (DATADISCONTINUITY);
  CHECK_OPTIONS_FLAG (TYPECHANGED);
  CHECK_OPTIONS_FLAG (TIMEVALID);
  CHECK_OPTIONS_FLAG (TIMEDISCONTINUITY);
  CHECK_OPTIONS_FLAG (FLUSHONPAUSE);
  CHECK_OPTIONS_FLAG (DURATIONVALID);
  CHECK_OPTIONS_FLAG (ENDOFSTREAM);
  CHECK_OPTIONS_FLAG (BUFFEREDTRANSFER);
  CHECK_OPTIONS_FLAG (VRAM_DATA_TRANSFER);
  CHECK_OPTIONS_FLAG (LOOPEDDATA);

  if (flags != 0)
    g_string_append_printf (str, "|0x%08x", (guint) flags);

  ret = str->str;
  g_string_free (str, FALSE);

  return ret;
}

typedef struct
{
  const GUID guid;
  const gchar *name;
} KsPropertySetMapping;

#ifndef STATIC_KSPROPSETID_GM
#define STATIC_KSPROPSETID_GM \
    0xAF627536, 0xE719, 0x11D2, { 0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D }
#endif
#ifndef STATIC_KSPROPSETID_Jack
#define STATIC_KSPROPSETID_Jack \
    0x4509F757, 0x2D46, 0x4637, { 0x8E, 0x62, 0xCE, 0x7D, 0xB9, 0x44, 0xF5, 0x7B }
#endif

#ifndef STATIC_PROPSETID_VIDCAP_SELECTOR
#define STATIC_PROPSETID_VIDCAP_SELECTOR \
    0x1ABDAECA, 0x68B6, 0x4F83, { 0x93, 0x71, 0xB4, 0x13, 0x90, 0x7C, 0x7B, 0x9F }
#endif
#ifndef STATIC_PROPSETID_EXT_DEVICE
#define STATIC_PROPSETID_EXT_DEVICE \
    0xB5730A90, 0x1A2C, 0x11cf, { 0x8c, 0x23, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 }
#endif
#ifndef STATIC_PROPSETID_EXT_TRANSPORT
#define STATIC_PROPSETID_EXT_TRANSPORT \
    0xA03CD5F0, 0x3045, 0x11cf, { 0x8c, 0x44, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 }
#endif
#ifndef STATIC_PROPSETID_TIMECODE_READER
#define STATIC_PROPSETID_TIMECODE_READER \
    0x9B496CE1, 0x811B, 0x11cf, { 0x8C, 0x77, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 }
#endif

static const KsPropertySetMapping known_property_sets[] = {
  {{STATIC_KSPROPSETID_General}, "General"},
  {{STATIC_KSPROPSETID_MediaSeeking}, "MediaSeeking"},
  {{STATIC_KSPROPSETID_Topology}, "Topology"},
  {{STATIC_KSPROPSETID_GM}, "GM"},
  {{STATIC_KSPROPSETID_Pin}, "Pin"},
  {{STATIC_KSPROPSETID_Quality}, "Quality"},
  {{STATIC_KSPROPSETID_Connection}, "Connection"},
  {{STATIC_KSPROPSETID_MemoryTransport}, "MemoryTransport"},
  {{STATIC_KSPROPSETID_StreamAllocator}, "StreamAllocator"},
  {{STATIC_KSPROPSETID_StreamInterface}, "StreamInterface"},
  {{STATIC_KSPROPSETID_Stream}, "Stream"},
  {{STATIC_KSPROPSETID_Clock}, "Clock"},

  {{STATIC_KSPROPSETID_DirectSound3DListener}, "DirectSound3DListener"},
  {{STATIC_KSPROPSETID_DirectSound3DBuffer}, "DirectSound3DBuffer"},
  {{STATIC_KSPROPSETID_Hrtf3d}, "Hrtf3d"},
  {{STATIC_KSPROPSETID_Itd3d}, "Itd3d"},
  {{STATIC_KSPROPSETID_Bibliographic}, "Bibliographic"},
  {{STATIC_KSPROPSETID_TopologyNode}, "TopologyNode"},
  {{STATIC_KSPROPSETID_RtAudio}, "RtAudio"},
  {{STATIC_KSPROPSETID_DrmAudioStream}, "DrmAudioStream"},
  {{STATIC_KSPROPSETID_Audio}, "Audio"},
  {{STATIC_KSPROPSETID_Acoustic_Echo_Cancel}, "Acoustic_Echo_Cancel"},
  {{STATIC_KSPROPSETID_Wave_Queued}, "Wave_Queued"},
  {{STATIC_KSPROPSETID_Wave}, "Wave"},
  {{STATIC_KSPROPSETID_WaveTable}, "WaveTable"},
  {{STATIC_KSPROPSETID_Cyclic}, "Cyclic"},
  {{STATIC_KSPROPSETID_Sysaudio}, "Sysaudio"},
  {{STATIC_KSPROPSETID_Sysaudio_Pin}, "Sysaudio_Pin"},
  {{STATIC_KSPROPSETID_AudioGfx}, "AudioGfx"},
  {{STATIC_KSPROPSETID_Linear}, "Linear"},
  {{STATIC_KSPROPSETID_Mpeg2Vid}, "Mpeg2Vid"},
  {{STATIC_KSPROPSETID_AC3}, "AC3"},
  {{STATIC_KSPROPSETID_AudioDecoderOut}, "AudioDecoderOut"},
  {{STATIC_KSPROPSETID_DvdSubPic}, "DvdSubPic"},
  {{STATIC_KSPROPSETID_CopyProt}, "CopyProt"},
  {{STATIC_KSPROPSETID_VBICAP_PROPERTIES}, "VBICAP_PROPERTIES"},
  {{STATIC_KSPROPSETID_VBICodecFiltering}, "VBICodecFiltering"},
  {{STATIC_KSPROPSETID_VramCapture}, "VramCapture"},
  {{STATIC_KSPROPSETID_OverlayUpdate}, "OverlayUpdate"},
  {{STATIC_KSPROPSETID_VPConfig}, "VPConfig"},
  {{STATIC_KSPROPSETID_VPVBIConfig}, "VPVBIConfig"},
  {{STATIC_KSPROPSETID_TSRateChange}, "TSRateChange"},
  {{STATIC_KSPROPSETID_Jack}, "Jack"},

  {{STATIC_PROPSETID_ALLOCATOR_CONTROL}, "ALLOCATOR_CONTROL"},
  {{STATIC_PROPSETID_VIDCAP_VIDEOPROCAMP}, "VIDCAP_VIDEOPROCAMP"},
  {{STATIC_PROPSETID_VIDCAP_SELECTOR}, "VIDCAP_SELECTOR"},
  {{STATIC_PROPSETID_TUNER}, "TUNER"},
  {{STATIC_PROPSETID_VIDCAP_VIDEOENCODER}, "VIDCAP_VIDEOENCODER"},
  {{STATIC_PROPSETID_VIDCAP_VIDEODECODER}, "VIDCAP_VIDEODECODER"},
  {{STATIC_PROPSETID_VIDCAP_CAMERACONTROL}, "VIDCAP_CAMERACONTROL"},
  {{STATIC_PROPSETID_EXT_DEVICE}, "EXT_DEVICE"},
  {{STATIC_PROPSETID_EXT_TRANSPORT}, "EXT_TRANSPORT"},
  {{STATIC_PROPSETID_TIMECODE_READER}, "TIMECODE_READER"},
  {{STATIC_PROPSETID_VIDCAP_CROSSBAR}, "VIDCAP_CROSSBAR"},
  {{STATIC_PROPSETID_VIDCAP_TVAUDIO}, "VIDCAP_TVAUDIO"},
  {{STATIC_PROPSETID_VIDCAP_VIDEOCOMPRESSION}, "VIDCAP_VIDEOCOMPRESSION"},
  {{STATIC_PROPSETID_VIDCAP_VIDEOCONTROL}, "VIDCAP_VIDEOCONTROL"},
  {{STATIC_PROPSETID_VIDCAP_DROPPEDFRAMES}, "VIDCAP_DROPPEDFRAMES"},
};

gchar *
ks_property_set_to_string (const GUID * guid)
{
  guint i;

  for (i = 0;
      i < sizeof (known_property_sets) / sizeof (known_property_sets[0]); i++) {
    if (IsEqualGUID (guid, &known_property_sets[i].guid))
      return g_strdup_printf ("KSPROPSETID_%s", known_property_sets[i].name);
  }

  return ks_guid_to_string (guid);
}
