/*
 * Copyright © Microsoft Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <stdio.h>
#include <stdbool.h>
#include <va/va_win32.h>
#include "va_display.h"
#include <directx/dxcore_interface.h>

extern "C" const char *g_device_name;

void dxcore_resolve_adapter(const char *adapter_string, /*out*/ bool* ptr_device_found, /*out*/ LUID* ptr_adapter_luid)
{
    int selected_adapter_index = -1;
    IDXCoreAdapterFactory *factory = nullptr;
    IDXCoreAdapterList *adapter_list = nullptr;
    IDXCoreAdapter *adapter = nullptr;
    typedef HRESULT(WINAPI * PFN_CREATE_DXCORE_ADAPTER_FACTORY)(REFIID riid, void **ppFactory);
    PFN_CREATE_DXCORE_ADAPTER_FACTORY DXCoreCreateAdapterFactory;
    HRESULT hr = S_OK;

    memset(ptr_adapter_luid, 0, sizeof(LUID));
    *ptr_device_found = false;

    HMODULE dxcore_mod = LoadLibrary("DXCore.DLL");
    if (!dxcore_mod) {
        fprintf(stderr, "Failed to load DXCore.DLL to enumerate adapters.\n");
        goto fail;
    }

    DXCoreCreateAdapterFactory = (PFN_CREATE_DXCORE_ADAPTER_FACTORY)GetProcAddress(dxcore_mod, "DXCoreCreateAdapterFactory");
    if (!DXCoreCreateAdapterFactory) {
        fprintf(stderr, "Failed to load DXCoreCreateAdapterFactory from DXCore.DLL.\n");
        goto fail;
    }

    hr = DXCoreCreateAdapterFactory(IID_IDXCoreAdapterFactory, (void **)&factory);
    if (FAILED(hr)) {
        fprintf(stderr, "DXCoreCreateAdapterFactory failed: %lx\n", hr);
        goto fail;
    }

    hr = factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS, IID_IDXCoreAdapterList, (void **)&adapter_list);
    if (FAILED(hr)) {
        fprintf(stderr, "CreateAdapterList failed: %lx\n", hr);
        goto fail;
    }

    if (adapter_string && (sscanf_s(adapter_string, "%d", &selected_adapter_index) != 1)) {
        fprintf(stderr, "Invalid device index received for -hwaccel_device %s\n", adapter_string ? adapter_string : "");
    }

    if (!adapter_string) fprintf(stdout, "Available devices for --display win32:\n");
    for (int i = 0; i < adapter_list->GetAdapterCount(); i++) {
        if (SUCCEEDED(adapter_list->GetAdapter(i, IID_IDXCoreAdapter, (void **)&adapter))) {
            size_t desc_size = 0;
            if (FAILED(adapter->GetPropertySize(DXCoreAdapterProperty::DriverDescription, &desc_size))) {
                adapter->Release();
                continue;
            }

            char *adapter_name = (char*)malloc(desc_size);
            if (!adapter_name) {
                adapter->Release();
                continue;
            }

            if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::DriverDescription, desc_size, adapter_name))) {
                free(adapter_name);
                adapter->Release();
                continue;
            }

            LUID cur_adapter_luid = { 0, 0 };
            if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::InstanceLuid, &cur_adapter_luid))) {
                free(adapter_name);
                adapter->Release();
                continue;
            }

            if (selected_adapter_index == i) {
                *ptr_adapter_luid = cur_adapter_luid;
                *ptr_device_found = true;
            }

            if (!adapter_string) fprintf(stdout, "\tDevice Index: %d Device LUID: %lu %ld - Device Name: %s\n", i, cur_adapter_luid.LowPart, cur_adapter_luid.HighPart, adapter_name);
            free(adapter_name);
            adapter->Release();
        }
    }

fail:
    if (adapter_list)
        adapter_list->Release();
    if (factory)
        factory->Release();
    if (dxcore_mod)
        FreeLibrary(dxcore_mod);
}

static VADisplay
va_open_display_win32(void)
{
    LUID adapter_luid = {0, 0};
    bool device_found = false;
    if (g_device_name) {
        bool print_devices = (0 == strcmp(g_device_name, "help"));
        dxcore_resolve_adapter(print_devices ? NULL : g_device_name, &device_found, &adapter_luid);
        if (print_devices) {
            exit(0);
        } else if (g_device_name && !device_found) {
            fprintf(stderr, "Could not find device %s for --display win32. Please try --device help for a list of available devices.\n", g_device_name);
            exit(0);
        }
    }

    // Adapter automatic selection supported by sending NULL adapter to vaGetDisplayWin32
    return vaGetDisplayWin32(device_found ? &adapter_luid : NULL);
}

static void
va_close_display_win32(VADisplay va_dpy)
{
}

static VAStatus
va_put_surface_win32(
    VADisplay          va_dpy,
    VASurfaceID        surface,
    const VARectangle *src_rect,
    const VARectangle *dst_rect
)
{
    return VA_STATUS_ERROR_OPERATION_FAILED;
}

#ifdef __cplusplus
extern "C" {
#endif

extern const VADisplayHooks va_display_hooks_win32 = {
    "win32",
    va_open_display_win32,
    va_close_display_win32,
    va_put_surface_win32,
};

#ifdef __cplusplus
}
#endif
