/*
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely.
*/

#include "testnative.h"

#ifdef TEST_NATIVE_WAYLAND

#include <SDL3/SDL.h>
#include <wayland-client.h>
#include <xdg-shell-client-protocol.h>

static void *native_userdata_ptr = (void *)0xBAADF00D;
static const char *native_surface_tag = "SDL_NativeSurfaceTag";

static void *CreateWindowWayland(int w, int h);
static void DestroyWindowWayland(void *window);

NativeWindowFactory WaylandWindowFactory = {
    "wayland",
    CreateWindowWayland,
    DestroyWindowWayland
};

/* Encapsulated in a struct to silence shadow variable warnings */
static struct _state
{
    struct wl_display *wl_display;
    struct wl_registry *wl_registry;
    struct wl_compositor *wl_compositor;
    struct xdg_wm_base *xdg_wm_base;
    struct wl_surface *wl_surface;
    struct xdg_surface *xdg_surface;
    struct xdg_toplevel *xdg_toplevel;
} state;

static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial)
{
    xdg_surface_ack_configure(state.xdg_surface, serial);
}

static const struct xdg_surface_listener xdg_surface_listener = {
    .configure = xdg_surface_configure,
};

static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states)
{
    /* NOP */
}

static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
{
    SDL_Event event;
    SDL_zero(event);

    event.type = SDL_EVENT_QUIT;
    SDL_PushEvent(&event);
}

static void xdg_toplevel_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
{
    /* NOP */
}

static void xdg_toplevel_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities)
{
    /* NOP */
}

static const struct xdg_toplevel_listener xdg_toplevel_listener = {
    .configure = xdg_toplevel_configure,
    .close = xdg_toplevel_close,
    .configure_bounds = xdg_toplevel_configure_bounds,
    .wm_capabilities = xdg_toplevel_wm_capabilities
};

static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
{
    xdg_wm_base_pong(state.xdg_wm_base, serial);
}

static const struct xdg_wm_base_listener xdg_wm_base_listener = {
    .ping = xdg_wm_base_ping,
};

static void registry_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version)
{
    if (SDL_strcmp(interface, wl_compositor_interface.name) == 0) {
        state.wl_compositor = wl_registry_bind(state.wl_registry, name, &wl_compositor_interface, SDL_min(version, 4));
    } else if (SDL_strcmp(interface, xdg_wm_base_interface.name) == 0) {
        state.xdg_wm_base = wl_registry_bind(state.wl_registry, name, &xdg_wm_base_interface, 1);
        xdg_wm_base_add_listener(state.xdg_wm_base, &xdg_wm_base_listener, NULL);
    }
}

static void registry_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
{
    /* NOP */
}

static const struct wl_registry_listener wl_registry_listener = {
    .global = registry_global,
    .global_remove = registry_global_remove,
};

static void *CreateWindowWayland(int w, int h)
{
    /* Export the display object from SDL and use it to create a registry object,
     * which will enumerate the wl_compositor and xdg_wm_base protocols.
     */
    state.wl_display = SDL_GetProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER, NULL);

    if (!state.wl_display) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid 'wl_display' object!");
        goto error;
    }

    state.wl_registry = wl_display_get_registry(state.wl_display);
    wl_registry_add_listener(state.wl_registry, &wl_registry_listener, NULL);

    /* Roundtrip to enumerate registry objects. */
    wl_display_roundtrip(state.wl_display);

    /* Protocol sanity check */
    if (!state.wl_compositor) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "'wl_compositor' protocol not found!");
        goto error;
    }
    if (!state.xdg_wm_base) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "'xdg_wm_base' protocol not found!");
        goto error;
    }

    /* Crate the backing wl_surface for the window. */
    state.wl_surface = wl_compositor_create_surface(state.wl_compositor);

    /* Set the native tag and userdata values, which should be the same at exit. */
    wl_proxy_set_tag((struct wl_proxy *)state.wl_surface, &native_surface_tag);
    wl_surface_set_user_data(state.wl_surface, native_userdata_ptr);

    /* Create the xdg_surface from the wl_surface. */
    state.xdg_surface = xdg_wm_base_get_xdg_surface(state.xdg_wm_base, state.wl_surface);
    xdg_surface_add_listener(state.xdg_surface, &xdg_surface_listener, NULL);

    /* Create the xdg_toplevel from the xdg_surface. */
    state.xdg_toplevel = xdg_surface_get_toplevel(state.xdg_surface);
    xdg_toplevel_add_listener(state.xdg_toplevel, &xdg_toplevel_listener, NULL);
    xdg_toplevel_set_title(state.xdg_toplevel, "Native Wayland Window");

    /* Return the wl_surface to be wrapped in an SDL_Window. */
    return state.wl_surface;

error:
    if (state.xdg_toplevel) {
        xdg_toplevel_destroy(state.xdg_toplevel);
        state.xdg_toplevel = NULL;
    }
    if (state.xdg_surface) {
        xdg_surface_destroy(state.xdg_surface);
        state.xdg_surface = NULL;
    }
    if (state.wl_surface) {
        wl_surface_destroy(state.wl_surface);
        state.wl_surface = NULL;
    }
    if (state.xdg_wm_base) {
        xdg_wm_base_destroy(state.xdg_wm_base);
        state.xdg_wm_base = NULL;
    }
    if (state.wl_compositor) {
        wl_compositor_destroy(state.wl_compositor);
        state.wl_compositor = NULL;
    }
    if (state.wl_registry) {
        wl_registry_destroy(state.wl_registry);
        state.wl_registry = NULL;
    }

    return NULL;
}

static void DestroyWindowWayland(void *window)
{
    if (state.xdg_toplevel) {
        xdg_toplevel_destroy(state.xdg_toplevel);
        state.xdg_toplevel = NULL;
    }
    if (state.xdg_surface) {
        xdg_surface_destroy(state.xdg_surface);
        state.xdg_surface = NULL;
    }
    if (state.wl_surface) {
        /* Surface sanity check; these should be unmodified. */
        if (wl_proxy_get_tag((struct wl_proxy *)state.wl_surface) != &native_surface_tag) {
            SDL_LogError(SDL_LOG_CATEGORY_ERROR, "The wl_surface tag was modified, this indicates a problem inside of SDL.");
        }
        if (wl_surface_get_user_data(state.wl_surface) != native_userdata_ptr) {
            SDL_LogError(SDL_LOG_CATEGORY_ERROR, "The wl_surface user data was modified, this indicates a problem inside of SDL.");
        }

        wl_surface_destroy(state.wl_surface);
        state.wl_surface = NULL;
    }
    if (state.xdg_wm_base) {
        xdg_wm_base_destroy(state.xdg_wm_base);
        state.xdg_wm_base = NULL;
    }
    if (state.wl_compositor) {
        wl_compositor_destroy(state.wl_compositor);
        state.wl_compositor = NULL;
    }
    if (state.wl_registry) {
        wl_registry_destroy(state.wl_registry);
        state.wl_registry = NULL;
    }
}

#endif
