//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// WaylandWindow.cpp: Implementation of OSWindow for Wayland

#include "util/linux/wayland/WaylandWindow.h"
#include "common/unsafe_buffers.h"

#include <linux/input-event-codes.h>
#include <sys/mman.h>
#include <sys/timerfd.h>
#include <unistd.h>

#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>

#include "common/debug.h"

// C++ workaround for Wayland macro
#define WL_ARRAY_FOR_EACH(pos, array, type) \
    for (pos = (type)(array)->data;         \
         (const char *)pos < ((const char *)(array)->data + (array)->size); (pos)++)

// The wl_display is intentionally process-scoped: per Wayland convention the
// connection lives for the lifetime of the process. Tying it to per-WaylandWindow
// lifetime breaks multi-window apps and corrupts Mesa Vulkan WSI internal state
// that retains wl_display proxy wrappers across vkCreateSwapchainKHR calls.
static struct wl_display *gDisplay = nullptr;
static bool gLocalDisplay          = false;

namespace
{
// Forward declaration so messageLoop (defined earlier in this file than the
// keymap table at the bottom) can call it for synthetic key-repeat events.
angle::KeyType LinuxKeyCodeToKey(uint32_t code);

void DisconnectGDisplayAtExit()
{
    if (gLocalDisplay && gDisplay)
    {
        wl_display_flush(gDisplay);
        wl_display_disconnect(gDisplay);
        gDisplay      = nullptr;
        gLocalDisplay = false;
    }
}
}  // namespace

WaylandWindow::WaylandWindow(void *nativeDisplay)
    : mCompositor{nullptr}, mSurface{nullptr}, mWindow{nullptr}
{
    if (nativeDisplay != nullptr)
    {
        if (gDisplay != nullptr && nativeDisplay != gDisplay)
        {
            if (gLocalDisplay)
            {
                wl_display_disconnect(gDisplay);
                gLocalDisplay = false;
            }
            fprintf(stderr, "WaylandWindow::WaylandWindow: Display reassignment\n");
        }
        gDisplay = reinterpret_cast<wl_display *>(nativeDisplay);
    }
    else if (!gDisplay)
    {
        gDisplay = wl_display_connect(nullptr);
        if (gDisplay)
        {
            gLocalDisplay = true;
            std::atexit(DisconnectGDisplayAtExit);
        }
    }
}

WaylandWindow::~WaylandWindow()
{
    destroy();
    // Do not disconnect gDisplay here: see the comment on the static above.
    // The atexit handler installed when we connected handles cleanup at
    // process exit so Valgrind doesn't see a leak.
}

void WaylandWindow::RegistryHandleGlobal(void *data,
                                         struct wl_registry *registry,
                                         uint32_t name,
                                         const char *interface,
                                         uint32_t version)
{
    WaylandWindow *vc = reinterpret_cast<WaylandWindow *>(data);

    if (ANGLE_UNSAFE_TODO(strcmp(interface, xdg_wm_base_interface.name)) == 0)
    {
        vc->mXdgWmBase = static_cast<xdg_wm_base *>(wl_registry_bind(
            registry, name, &xdg_wm_base_interface, std::min(static_cast<uint32_t>(3), version)));
        xdg_wm_base_add_listener(vc->mXdgWmBase, &xdg_wm_base_listener, data);
    }
    else if (ANGLE_UNSAFE_TODO(strcmp(interface, wl_compositor_interface.name)) == 0)
    {
        // v4+ is needed for wl_surface.damage_buffer (opcode 9). Cap at 4 since
        // we don't use later additions (v5 offset / v6 preferred_buffer_*).
        vc->mCompositor = static_cast<wl_compositor *>(wl_registry_bind(
            registry, name, &wl_compositor_interface, std::min(static_cast<uint32_t>(4), version)));
    }
    else if (ANGLE_UNSAFE_TODO(strcmp(interface, wl_seat_interface.name)) == 0)
    {
        // v5+ gives us pointer.frame / axis_discrete; clamp to 5 since that
        // covers every common compositor and our pointer listener stops there.
        vc->mSeat = static_cast<wl_seat *>(wl_registry_bind(
            registry, name, &wl_seat_interface, std::min(static_cast<uint32_t>(5), version)));
        wl_seat_add_listener(vc->mSeat, &seat_listener, vc);
    }
    else if (ANGLE_UNSAFE_TODO(strcmp(interface, wl_shm_interface.name)) == 0)
    {
        // Bound for the setVisible(true) placeholder buffer. Version 1 is
        // sufficient -- we only use create_pool/create_buffer.
        vc->mShm = static_cast<wl_shm *>(wl_registry_bind(registry, name, &wl_shm_interface, 1));
    }
    else if (ANGLE_UNSAFE_TODO(strcmp(interface, zxdg_decoration_manager_v1_interface.name)) == 0)
    {
        // Optional global. Compositors that don't advertise it leave this
        // null; the window is then decorationless.
        vc->mDecorationManager = static_cast<zxdg_decoration_manager_v1 *>(
            wl_registry_bind(registry, name, &zxdg_decoration_manager_v1_interface, 1));
    }
}

void WaylandWindow::RegistryHandleGlobalRemove(void *data,
                                               struct wl_registry *registry,
                                               uint32_t name)
{}

const struct wl_registry_listener WaylandWindow::registryListener = {
    WaylandWindow::RegistryHandleGlobal, WaylandWindow::RegistryHandleGlobalRemove};

bool WaylandWindow::initializeImpl(const std::string &name, int width, int height)
{
    destroy();

    if (!gDisplay)
    {
        gDisplay      = wl_display_connect(nullptr);
        gLocalDisplay = true;
        if (!gDisplay)
        {
            return false;
        }
    }

    // Get registry of display
    struct wl_registry *registry = wl_display_get_registry(gDisplay);
    wl_registry_add_listener(registry, &registryListener, this);

    // Round-trip to get globals
    wl_display_roundtrip(gDisplay);
    if (!mCompositor)
    {
        return false;
    }

    // We don't need this anymore; we don't track output changes
    wl_registry_destroy(registry);

    mSurface = wl_compositor_create_surface(mCompositor);
    if (!mSurface)
    {
        return false;
    }

    {
        mXdgSurface = xdg_wm_base_get_xdg_surface(mXdgWmBase, mSurface);
        xdg_surface_add_listener(mXdgSurface, &xdg_surface_listener, this);

        mXdgToplevel = xdg_surface_get_toplevel(mXdgSurface);
        xdg_toplevel_add_listener(mXdgToplevel, &xdg_toplevel_listener, this);
        xdg_toplevel_set_app_id(mXdgToplevel, name.c_str());
        xdg_toplevel_set_title(mXdgToplevel, name.c_str());

        // Request server-side decorations. Must happen before the initial
        // surface commit so the first configure carries the granted mode.
        // Null mDecorationManager means the compositor doesn't expose the
        // protocol; the window is then decorationless.
        if (mDecorationManager)
        {
            mToplevelDecoration = zxdg_decoration_manager_v1_get_toplevel_decoration(
                mDecorationManager, mXdgToplevel);
            zxdg_toplevel_decoration_v1_add_listener(mToplevelDecoration, &decoration_listener,
                                                     this);
            zxdg_toplevel_decoration_v1_set_mode(mToplevelDecoration,
                                                 ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
        }

        mWaitForConfigure = true;
        wl_surface_commit(mSurface);
        while (mWaitForConfigure)
        {
            if (wl_display_dispatch(gDisplay) < 0)
            {
                break;
            }
        }
    }

    mWindow = wl_egl_window_create(mSurface, width, height);
    if (!mWindow)
    {
        return false;
    }

    fds[0] = {wl_display_get_fd(gDisplay), POLLIN, 0};
    // Lazy-create the key-repeat timerfd (one per WaylandWindow). Closed in
    // destroy(). Non-blocking + cloexec is the Wayland-client convention.
    if (mRepeatTimerFd < 0)
    {
        mRepeatTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
    }
    fds[1] = {mRepeatTimerFd, POLLIN, 0};

    mY      = 0;
    mX      = 0;
    mWidth  = width;
    mHeight = height;

    return true;
}

void WaylandWindow::disableErrorMessageDialog() {}

void WaylandWindow::destroy()
{
    // Tear down in reverse-dependency order so children are released before
    // their parents: input objects -> wl_egl_window -> wl_surface chain ->
    // wl_seat / xdg_wm_base / wl_compositor (the registry globals).
    if (mKeyboard)
    {
        wl_keyboard_release(mKeyboard);
        mKeyboard = nullptr;
    }
    if (mPointer)
    {
        wl_pointer_release(mPointer);
        mPointer = nullptr;
    }
    if (mSeat)
    {
        wl_seat_destroy(mSeat);
        mSeat = nullptr;
    }

    if (mRepeatTimerFd >= 0)
    {
        close(mRepeatTimerFd);
        mRepeatTimerFd = -1;
        mRepeatKey     = 0;
    }

    releaseShmPlaceholder();
    mEglHandoffComplete = false;

    if (mShm)
    {
        wl_shm_destroy(mShm);
        mShm = nullptr;
    }

    if (mWindow)
    {
        wl_egl_window_destroy(mWindow);
        mWindow = nullptr;
    }

    // The toplevel_decoration is a child of xdg_toplevel; release it first.
    if (mToplevelDecoration)
    {
        zxdg_toplevel_decoration_v1_destroy(mToplevelDecoration);
        mToplevelDecoration = nullptr;
    }

    if (mXdgToplevel)
    {
        xdg_toplevel_destroy(mXdgToplevel);
        mXdgToplevel = nullptr;
    }

    if (mXdgSurface)
    {
        xdg_surface_destroy(mXdgSurface);
        mXdgSurface = nullptr;
    }

    if (mSurface)
    {
        wl_surface_destroy(mSurface);
        mSurface = nullptr;
    }

    if (mDecorationManager)
    {
        zxdg_decoration_manager_v1_destroy(mDecorationManager);
        mDecorationManager = nullptr;
    }

    if (mXdgWmBase)
    {
        xdg_wm_base_destroy(mXdgWmBase);
        mXdgWmBase = nullptr;
    }

    if (mCompositor)
    {
        wl_compositor_destroy(mCompositor);
        mCompositor = nullptr;
    }
}

void WaylandWindow::resetNativeWindow() {}

void WaylandWindow::setNativeDisplay(EGLNativeDisplayType display)
{
    wl_display *newDisplay = reinterpret_cast<wl_display *>(display);
    if (gDisplay != nullptr && newDisplay != gDisplay)
    {
        if (gLocalDisplay)
        {
            // A window opened a local connection we haven't created surfaces
            // on yet; drop it and use the display provided by the caller.
            wl_display_disconnect(gDisplay);
            gLocalDisplay = false;
        }
        fprintf(stderr, "WaylandWindow::setNativeDisplay: Display reassignment\n");
    }
    gDisplay = newDisplay;
}

EGLNativeWindowType WaylandWindow::getNativeWindow() const
{
    // First call hands the wl_surface to EGL (the caller passes this to
    // eglCreateWindowSurface or an equivalent path used by dEQP and the
    // perf tests). Retire the shm placeholder so subsequent setVisible/
    // resize stop touching the surface behind EGL's back.
    if (!mEglHandoffComplete)
    {
        mEglHandoffComplete = true;
        releaseShmPlaceholder();
    }
    return reinterpret_cast<EGLNativeWindowType>(mWindow);
}

EGLNativeDisplayType WaylandWindow::getNativeDisplay() const
{
    return reinterpret_cast<EGLNativeDisplayType>(gDisplay);
}

EGLenum WaylandWindow::getNativeDisplayPlatformType() const
{
    return EGL_PLATFORM_WAYLAND_EXT;
}

void WaylandWindow::messageLoop()
{
    while (wl_display_prepare_read(gDisplay) != 0)
    {
        wl_display_dispatch_pending(gDisplay);
    }
    if (wl_display_flush(gDisplay) < 0 && errno != EAGAIN)
    {
        wl_display_cancel_read(gDisplay);
        return;
    }

    // Poll both wayland and the repeat timer. Timeout 0 = non-blocking; this
    // function is invoked from a tight render loop, so we never want to wait.
    const nfds_t nfds = (mRepeatTimerFd >= 0) ? 2 : 1;
    const int ret     = poll(fds, nfds, 0);

    if (ret > 0 && (fds[0].revents & POLLIN))
    {
        wl_display_read_events(gDisplay);
        wl_display_dispatch_pending(gDisplay);
    }
    else
    {
        wl_display_cancel_read(gDisplay);
    }

    if (ret > 0 && nfds > 1 && (fds[1].revents & POLLIN) && mRepeatKey != 0)
    {
        uint64_t expirations = 0;
        if (read(mRepeatTimerFd, &expirations, sizeof(expirations)) == sizeof(expirations))
        {
            // Cap to a sane upper bound so a stalled loop catching up doesn't
            // dump hundreds of synthetic key events at once.
            const uint64_t kMaxBurst = 8;
            const uint64_t n         = std::min(expirations, kMaxBurst);
            for (uint64_t i = 0; i < n; ++i)
            {
                Event event{};
                event.Type        = Event::EVENT_KEY_PRESSED;
                event.Key.Code    = LinuxKeyCodeToKey(mRepeatKey);
                event.Key.Shift   = mShiftDown;
                event.Key.Control = mControlDown;
                event.Key.Alt     = mAltDown;
                event.Key.System  = mSuperDown;
                pushEvent(std::move(event));
            }
        }
    }
}

void WaylandWindow::setMousePosition(int x, int y) {}

bool WaylandWindow::setOrientation(int /*width*/, int /*height*/)
{
    UNIMPLEMENTED();
    return false;
}

bool WaylandWindow::setPosition(int /*x*/, int /*y*/)
{
    // Wayland forbids client-initiated absolute window positioning; the
    // compositor places toplevels. Returning true keeps the OSWindow contract
    // for callers that don't gate on the result.
    return true;
}

bool WaylandWindow::resize(int width, int height)
{
    // mWindow may be null during the initial xdg_toplevel configure (which can
    // arrive before initializeImpl creates the wl_egl_window).
    if (mWindow)
    {
        wl_egl_window_resize(mWindow, width, height, 0, 0);
    }

    // pushEvent below updates mWidth/mHeight via OSWindow::pushEvent; do it now
    // so ensureShmBuffer (which reads mWidth/mHeight) sees the new dimensions.
    const bool sizeChanged = (width != mWidth || height != mHeight);
    if (sizeChanged)
    {
        Event event{};
        event.Type        = Event::EVENT_RESIZED;
        event.Size.Width  = width;
        event.Size.Height = height;
        pushEvent(std::move(event));
    }

    // Reallocate the placeholder for the new size, only while we still own
    // the surface. After handoff mShmBuffer is null and this block is
    // skipped; EGL handles resize via wl_egl_window_resize above.
    if (sizeChanged && mVisible && mShmBuffer && mSurface && mShm)
    {
        wl_buffer_destroy(mShmBuffer);
        mShmBuffer       = nullptr;
        mShmBufferWidth  = 0;
        mShmBufferHeight = 0;
        if (ensureShmBuffer())
        {
            wl_surface_attach(mSurface, mShmBuffer, 0, 0);
            wl_surface_damage_buffer(mSurface, 0, 0, mShmBufferWidth, mShmBufferHeight);
            wl_surface_commit(mSurface);
            wl_display_flush(gDisplay);
        }
    }

    return true;
}

bool WaylandWindow::ensureShmBuffer()
{
    if (mShmBuffer != nullptr)
    {
        return true;
    }
    if (!mShm)
    {
        // Compositor didn't advertise wl_shm; nothing we can attach.
        return false;
    }

    const int32_t width  = mWidth > 0 ? mWidth : 1;
    const int32_t height = mHeight > 0 ? mHeight : 1;
    const int32_t stride = width * 4;
    const off_t size     = static_cast<off_t>(stride) * height;

    int fd = memfd_create("waylandwindow-shm", MFD_CLOEXEC);
    if (fd < 0)
    {
        return false;
    }
    if (ftruncate(fd, size) < 0)
    {
        close(fd);
        return false;
    }

    void *data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (data == MAP_FAILED)
    {
        close(fd);
        return false;
    }

    // Fill with opaque dark gray so a surface that never gets EGL-rendered
    // still has visible pixels. WL_SHM_FORMAT_ARGB8888 specifies the byte
    // sequence B, G, R, A in memory regardless of CPU endianness, so we
    // write bytes directly rather than a uint32_t.
    static constexpr uint8_t kPixel[4] = {0x20, 0x20, 0x20, 0xFF};  // B, G, R, A
    uint8_t *bytes                     = static_cast<uint8_t *>(data);
    for (int32_t i = 0; i < width * height; ++i)
    {
        ANGLE_UNSAFE_TODO(std::memcpy(bytes + i * 4, kPixel, sizeof(kPixel)));
    }
    munmap(data, size);

    struct wl_shm_pool *pool = wl_shm_create_pool(mShm, fd, static_cast<int32_t>(size));
    mShmBuffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
    wl_shm_pool_destroy(pool);
    close(fd);

    if (!mShmBuffer)
    {
        return false;
    }
    mShmBufferWidth  = width;
    mShmBufferHeight = height;
    return true;
}

void WaylandWindow::releaseShmPlaceholder() const
{
    if (mShmBuffer)
    {
        wl_buffer_destroy(mShmBuffer);
        mShmBuffer       = nullptr;
        mShmBufferWidth  = 0;
        mShmBufferHeight = 0;
    }
}

void WaylandWindow::setVisible(bool isVisible)
{
    // Idempotent: skip the protocol round-trip if state already matches.
    if (mVisible == isVisible)
    {
        return;
    }

    if (!mSurface || !gDisplay)
    {
        return;
    }

    // After EGL handoff the swap chain owns the wl_surface; only the
    // visibility flag can change here. The compositor keeps showing
    // EGL's most recent frame until eglSwapBuffers replaces it.
    if (mEglHandoffComplete)
    {
        mVisible = isVisible;
        return;
    }

    if (isVisible)
    {
        // Compositors ignore xdg_toplevel until they see a buffered
        // surface, so map by attaching the placeholder + committing.
        if (!ensureShmBuffer())
        {
            return;
        }
        wl_surface_attach(mSurface, mShmBuffer, 0, 0);
        wl_surface_damage_buffer(mSurface, 0, 0, mShmBufferWidth, mShmBufferHeight);
        wl_surface_commit(mSurface);
    }
    else
    {
        // Unmap: NULL buffer attach + commit. The compositor removes the
        // surface from screen until a new buffer is attached.
        wl_surface_attach(mSurface, nullptr, 0, 0);
        wl_surface_commit(mSurface);
    }

    mVisible = isVisible;
    wl_display_flush(gDisplay);
}

void WaylandWindow::signalTestEvent()
{
    Event event{};
    event.Type = Event::EVENT_TEST;
    pushEvent(std::move(event));
}

void WaylandWindow::xdg_wm_base_ping(void * /* data */,
                                     struct xdg_wm_base *xdg_wm_base,
                                     uint32_t serial)
{
    xdg_wm_base_pong(xdg_wm_base, serial);
}

const struct xdg_wm_base_listener WaylandWindow::xdg_wm_base_listener = {
    .ping = xdg_wm_base_ping,
};

void WaylandWindow::handle_xdg_surface_configure(void *data,
                                                 struct xdg_surface *xdg_surface,
                                                 uint32_t serial)
{
    auto *w = static_cast<WaylandWindow *>(data);
    xdg_surface_ack_configure(xdg_surface, serial);
    w->mWaitForConfigure = false;
}

const struct xdg_surface_listener WaylandWindow::xdg_surface_listener = {
    .configure = handle_xdg_surface_configure};

void WaylandWindow::handle_toplevel_configure(void *data,
                                              struct xdg_toplevel * /* toplevel */,
                                              int32_t width,
                                              int32_t height,
                                              struct wl_array *states)
{
    auto *w = static_cast<WaylandWindow *>(data);

    // Snapshot mActivated before recomputing so GAINED/LOST fire exactly once
    // per real focus change. The activated bit is the WM-level focus signal;
    // wl_keyboard enter/leave is input-routing and is unreliable (headless
    // compositors don't advertise a keyboard capability).
    const bool wasActivated = w->mActivated;
    w->mFullscreen          = false;
    w->mMaximized           = false;
    w->mResize              = false;
    w->mActivated           = false;

    const uint32_t *state;
    ANGLE_UNSAFE_TODO(WL_ARRAY_FOR_EACH(state, states, const uint32_t *))
    {
        switch (*state)
        {
            case XDG_TOPLEVEL_STATE_FULLSCREEN:
                w->mFullscreen = true;
                break;
            case XDG_TOPLEVEL_STATE_MAXIMIZED:
                w->mMaximized = true;
                break;
            case XDG_TOPLEVEL_STATE_RESIZING:
                // EVENT_RESIZED is emitted from WaylandWindow::resize() below,
                // using the post-clamp mGeometry -- the raw configure (width,
                // height) here can be (0, 0) meaning "client picks".
                w->mResize = true;
                break;
            case XDG_TOPLEVEL_STATE_ACTIVATED:
                w->mActivated = true;
                break;
        }
    }

    if (w->mActivated != wasActivated)
    {
        Event event{};
        event.Type = w->mActivated ? Event::EVENT_GAINED_FOCUS : Event::EVENT_LOST_FOCUS;
        w->pushEvent(std::move(event));
    }

    if (width > 0 && height > 0)
    {
        if (!w->mFullscreen && !w->mMaximized)
        {
            w->mWindowSize.width  = width;
            w->mWindowSize.height = height;
        }
        w->mGeometry.width  = width;
        w->mGeometry.height = height;
    }
    else if (!w->mFullscreen && !w->mMaximized)
    {
        w->mGeometry.width  = w->mWindowSize.width;
        w->mGeometry.height = w->mWindowSize.height;
    }

    w->resize(w->mGeometry.width, w->mGeometry.height);
}

void WaylandWindow::handle_toplevel_close(void *data, struct xdg_toplevel * /* xdg_toplevel */)
{
    auto *w = static_cast<WaylandWindow *>(data);

    Event event{};
    event.Type = Event::EVENT_CLOSED;
    w->pushEvent(std::move(event));
}

const struct xdg_toplevel_listener WaylandWindow::xdg_toplevel_listener = {
    .configure        = handle_toplevel_configure,
    .close            = handle_toplevel_close,
    .configure_bounds = nullptr,
    .wm_capabilities  = nullptr,
};

void WaylandWindow::decoration_configure(void * /*data*/,
                                         struct zxdg_toplevel_decoration_v1 * /*decoration*/,
                                         uint32_t mode)
{
    // We only ever request SERVER_SIDE. A CLIENT_SIDE response leaves the
    // window decorationless (we don't draw our own chrome) -- log so the
    // missing decorations are debuggable rather than mysterious.
    if (mode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)
    {
        fprintf(stderr,
                "WaylandWindow: compositor refused SERVER_SIDE decorations "
                "(mode=%u); window will be undecorated.\n",
                mode);
    }
}

const struct zxdg_toplevel_decoration_v1_listener WaylandWindow::decoration_listener = {
    .configure = decoration_configure,
};

// --- Input ----------------------------------------------------------------
//
// Wayland delivers key events as raw Linux input-event-codes (KEY_*) and
// mouse button events as raw codes (BTN_*). We translate directly to ANGLE's
// KeyType / MouseButtonType enums and intentionally skip xkbcommon-based
// keymap translation: this code path is for key identification, not text
// entry. EVENT_TEXT_ENTERED is unimplemented (matches the X11 backend).

namespace
{
angle::KeyType LinuxKeyCodeToKey(uint32_t code)
{
    switch (code)
    {
        case KEY_ESC:
            return angle::KeyType::ESCAPE;
        case KEY_1:
            return angle::KeyType::NUM1;
        case KEY_2:
            return angle::KeyType::NUM2;
        case KEY_3:
            return angle::KeyType::NUM3;
        case KEY_4:
            return angle::KeyType::NUM4;
        case KEY_5:
            return angle::KeyType::NUM5;
        case KEY_6:
            return angle::KeyType::NUM6;
        case KEY_7:
            return angle::KeyType::NUM7;
        case KEY_8:
            return angle::KeyType::NUM8;
        case KEY_9:
            return angle::KeyType::NUM9;
        case KEY_0:
            return angle::KeyType::NUM0;
        case KEY_MINUS:
            return angle::KeyType::DASH;
        case KEY_EQUAL:
            return angle::KeyType::EQUAL;
        case KEY_BACKSPACE:
            return angle::KeyType::BACK;
        case KEY_TAB:
            return angle::KeyType::TAB;
        case KEY_Q:
            return angle::KeyType::Q;
        case KEY_W:
            return angle::KeyType::W;
        case KEY_E:
            return angle::KeyType::E;
        case KEY_R:
            return angle::KeyType::R;
        case KEY_T:
            return angle::KeyType::T;
        case KEY_Y:
            return angle::KeyType::Y;
        case KEY_U:
            return angle::KeyType::U;
        case KEY_I:
            return angle::KeyType::I;
        case KEY_O:
            return angle::KeyType::O;
        case KEY_P:
            return angle::KeyType::P;
        case KEY_LEFTBRACE:
            return angle::KeyType::LBRACKET;
        case KEY_RIGHTBRACE:
            return angle::KeyType::RBRACKET;
        case KEY_ENTER:
            return angle::KeyType::RETURN;
        case KEY_LEFTCTRL:
            return angle::KeyType::LCONTROL;
        case KEY_A:
            return angle::KeyType::A;
        case KEY_S:
            return angle::KeyType::S;
        case KEY_D:
            return angle::KeyType::D;
        case KEY_F:
            return angle::KeyType::F;
        case KEY_G:
            return angle::KeyType::G;
        case KEY_H:
            return angle::KeyType::H;
        case KEY_J:
            return angle::KeyType::J;
        case KEY_K:
            return angle::KeyType::K;
        case KEY_L:
            return angle::KeyType::L;
        case KEY_SEMICOLON:
            return angle::KeyType::SEMICOLON;
        case KEY_APOSTROPHE:
            return angle::KeyType::QUOTE;
        case KEY_GRAVE:
            return angle::KeyType::TILDE;
        case KEY_LEFTSHIFT:
            return angle::KeyType::LSHIFT;
        case KEY_BACKSLASH:
            return angle::KeyType::BACKSLASH;
        case KEY_Z:
            return angle::KeyType::Z;
        case KEY_X:
            return angle::KeyType::X;
        case KEY_C:
            return angle::KeyType::C;
        case KEY_V:
            return angle::KeyType::V;
        case KEY_B:
            return angle::KeyType::B;
        case KEY_N:
            return angle::KeyType::N;
        case KEY_M:
            return angle::KeyType::M;
        case KEY_COMMA:
            return angle::KeyType::COMMA;
        case KEY_DOT:
            return angle::KeyType::PERIOD;
        case KEY_SLASH:
            return angle::KeyType::SLASH;
        case KEY_RIGHTSHIFT:
            return angle::KeyType::RSHIFT;
        case KEY_KPASTERISK:
            return angle::KeyType::MULTIPLY;
        case KEY_LEFTALT:
            return angle::KeyType::LALT;
        case KEY_SPACE:
            return angle::KeyType::SPACE;
        case KEY_F1:
            return angle::KeyType::F1;
        case KEY_F2:
            return angle::KeyType::F2;
        case KEY_F3:
            return angle::KeyType::F3;
        case KEY_F4:
            return angle::KeyType::F4;
        case KEY_F5:
            return angle::KeyType::F5;
        case KEY_F6:
            return angle::KeyType::F6;
        case KEY_F7:
            return angle::KeyType::F7;
        case KEY_F8:
            return angle::KeyType::F8;
        case KEY_F9:
            return angle::KeyType::F9;
        case KEY_F10:
            return angle::KeyType::F10;
        case KEY_KP7:
            return angle::KeyType::NUMPAD7;
        case KEY_KP8:
            return angle::KeyType::NUMPAD8;
        case KEY_KP9:
            return angle::KeyType::NUMPAD9;
        case KEY_KPMINUS:
            return angle::KeyType::SUBTRACT;
        case KEY_KP4:
            return angle::KeyType::NUMPAD4;
        case KEY_KP5:
            return angle::KeyType::NUMPAD5;
        case KEY_KP6:
            return angle::KeyType::NUMPAD6;
        case KEY_KPPLUS:
            return angle::KeyType::ADD;
        case KEY_KP1:
            return angle::KeyType::NUMPAD1;
        case KEY_KP2:
            return angle::KeyType::NUMPAD2;
        case KEY_KP3:
            return angle::KeyType::NUMPAD3;
        case KEY_KP0:
            return angle::KeyType::NUMPAD0;
        case KEY_F11:
            return angle::KeyType::F11;
        case KEY_F12:
            return angle::KeyType::F12;
        case KEY_F13:
            return angle::KeyType::F13;
        case KEY_F14:
            return angle::KeyType::F14;
        case KEY_F15:
            return angle::KeyType::F15;
        case KEY_KPSLASH:
            return angle::KeyType::DIVIDE;
        case KEY_RIGHTALT:
            return angle::KeyType::RALT;
        case KEY_HOME:
            return angle::KeyType::HOME;
        case KEY_UP:
            return angle::KeyType::UP;
        case KEY_PAGEUP:
            return angle::KeyType::PAGEUP;
        case KEY_LEFT:
            return angle::KeyType::LEFT;
        case KEY_RIGHT:
            return angle::KeyType::RIGHT;
        case KEY_END:
            return angle::KeyType::END;
        case KEY_DOWN:
            return angle::KeyType::DOWN;
        case KEY_PAGEDOWN:
            return angle::KeyType::PAGEDOWN;
        case KEY_INSERT:
            return angle::KeyType::INSERT;
        case KEY_DELETE:
            return angle::KeyType::DEL;
        case KEY_PAUSE:
            return angle::KeyType::PAUSE;
        case KEY_LEFTMETA:
            return angle::KeyType::LSYSTEM;
        case KEY_RIGHTMETA:
            return angle::KeyType::RSYSTEM;
        case KEY_RIGHTCTRL:
            return angle::KeyType::RCONTROL;
        case KEY_MENU:
            return angle::KeyType::MENU;
        default:
            return angle::KeyType(0);
    }
}

angle::MouseButtonType LinuxButtonToMouseButton(uint32_t button)
{
    switch (button)
    {
        case BTN_LEFT:
            return angle::MouseButtonType::LEFT;
        case BTN_RIGHT:
            return angle::MouseButtonType::RIGHT;
        case BTN_MIDDLE:
            return angle::MouseButtonType::MIDDLE;
        case BTN_SIDE:
            return angle::MouseButtonType::BUTTON4;
        case BTN_EXTRA:
            return angle::MouseButtonType::BUTTON5;
        default:
            return angle::MouseButtonType::UNKNOWN;
    }
}
}  // namespace

void WaylandWindow::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
{
    auto *w = static_cast<WaylandWindow *>(data);

    const bool wantKeyboard = (caps & WL_SEAT_CAPABILITY_KEYBOARD) != 0;
    if (wantKeyboard && !w->mKeyboard)
    {
        w->mKeyboard = wl_seat_get_keyboard(seat);
        wl_keyboard_add_listener(w->mKeyboard, &keyboard_listener, w);
    }
    else if (!wantKeyboard && w->mKeyboard)
    {
        wl_keyboard_release(w->mKeyboard);
        w->mKeyboard = nullptr;
    }

    const bool wantPointer = (caps & WL_SEAT_CAPABILITY_POINTER) != 0;
    if (wantPointer && !w->mPointer)
    {
        w->mPointer = wl_seat_get_pointer(seat);
        wl_pointer_add_listener(w->mPointer, &pointer_listener, w);
    }
    else if (!wantPointer && w->mPointer)
    {
        wl_pointer_release(w->mPointer);
        w->mPointer = nullptr;
    }
}

void WaylandWindow::seat_name(void * /*data*/, struct wl_seat * /*seat*/, const char * /*name*/) {}

const struct wl_seat_listener WaylandWindow::seat_listener = {
    .capabilities = seat_capabilities,
    .name         = seat_name,
};

void WaylandWindow::keyboard_keymap(void * /*data*/,
                                    struct wl_keyboard * /*keyboard*/,
                                    uint32_t /*format*/,
                                    int32_t fd,
                                    uint32_t /*size*/)
{
    // We don't translate via xkbcommon; close the fd the compositor mmap'd for
    // us to keep the file table tidy (libwayland-client always sends one).
    close(fd);
}

void WaylandWindow::keyboard_enter(void * /*data*/,
                                   struct wl_keyboard * /*keyboard*/,
                                   uint32_t /*serial*/,
                                   struct wl_surface * /*surface*/,
                                   struct wl_array * /*keys*/)
{
    // Focus events come from xdg_toplevel.state.activated (see
    // handle_toplevel_configure), not from keyboard enter/leave. The
    // activated bit is the WM-level focus signal and works even when the
    // compositor doesn't advertise a keyboard capability.
}

void WaylandWindow::keyboard_leave(void *data,
                                   struct wl_keyboard * /*keyboard*/,
                                   uint32_t /*serial*/,
                                   struct wl_surface * /*surface*/)
{
    // Stop any in-flight key repeat -- the user can no longer release the held
    // key for this surface, so repeats would fire forever. (No focus event is
    // pushed here; see keyboard_enter comment.)
    auto *w = static_cast<WaylandWindow *>(data);
    if (w->mRepeatTimerFd >= 0 && w->mRepeatKey != 0)
    {
        struct itimerspec ts{};
        timerfd_settime(w->mRepeatTimerFd, 0, &ts, nullptr);
        w->mRepeatKey = 0;
    }
}

void WaylandWindow::keyboard_key(void *data,
                                 struct wl_keyboard * /*keyboard*/,
                                 uint32_t /*serial*/,
                                 uint32_t /*time*/,
                                 uint32_t key,
                                 uint32_t state)
{
    auto *w = static_cast<WaylandWindow *>(data);

    Event event{};
    event.Type        = (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? Event::EVENT_KEY_PRESSED
                                                                 : Event::EVENT_KEY_RELEASED;
    event.Key.Code    = LinuxKeyCodeToKey(key);
    event.Key.Shift   = w->mShiftDown;
    event.Key.Control = w->mControlDown;
    event.Key.Alt     = w->mAltDown;
    event.Key.System  = w->mSuperDown;
    w->pushEvent(std::move(event));

    // Drive key auto-repeat ourselves to match X11/Win32 semantics -- Wayland
    // does not generate repeat events. Only non-modifier keys repeat (matches
    // libinput's default behavior and avoids spamming Shift/Ctrl events).
    if (w->mRepeatTimerFd < 0)
    {
        return;
    }
    const bool isModifier = (key == KEY_LEFTSHIFT || key == KEY_RIGHTSHIFT || key == KEY_LEFTCTRL ||
                             key == KEY_RIGHTCTRL || key == KEY_LEFTALT || key == KEY_RIGHTALT ||
                             key == KEY_LEFTMETA || key == KEY_RIGHTMETA);
    struct itimerspec ts{};
    if (state == WL_KEYBOARD_KEY_STATE_PRESSED && !isModifier && w->mRepeatRate > 0)
    {
        w->mRepeatKey            = key;
        const int64_t intervalNs = 1'000'000'000LL / w->mRepeatRate;
        ts.it_value.tv_sec       = w->mRepeatDelay / 1000;
        ts.it_value.tv_nsec      = (w->mRepeatDelay % 1000) * 1'000'000;
        ts.it_interval.tv_sec    = static_cast<time_t>(intervalNs / 1'000'000'000LL);
        ts.it_interval.tv_nsec   = static_cast<long>(intervalNs % 1'000'000'000LL);
        timerfd_settime(w->mRepeatTimerFd, 0, &ts, nullptr);
    }
    else if (state == WL_KEYBOARD_KEY_STATE_RELEASED && key == w->mRepeatKey)
    {
        // Disarm only on release of the key we were repeating. Releasing some
        // other key (e.g., Shift while W is still held) leaves W repeating.
        timerfd_settime(w->mRepeatTimerFd, 0, &ts, nullptr);
        w->mRepeatKey = 0;
    }
}

void WaylandWindow::keyboard_modifiers(void *data,
                                       struct wl_keyboard * /*keyboard*/,
                                       uint32_t /*serial*/,
                                       uint32_t mods_depressed,
                                       uint32_t /*mods_latched*/,
                                       uint32_t /*mods_locked*/,
                                       uint32_t /*group*/)
{
    // wl_keyboard.modifiers reports the active xkb modifier mask. Without a
    // keymap we don't know which xkb bit is Shift, but compositors using the
    // default libxkbcommon layout set bit 0=Shift, 2=Control, 3=Alt (Mod1),
    // 6=Super (Mod4) -- sufficient for non-text-entry key dispatch.
    auto *w         = static_cast<WaylandWindow *>(data);
    w->mShiftDown   = (mods_depressed & (1u << 0)) != 0;
    w->mControlDown = (mods_depressed & (1u << 2)) != 0;
    w->mAltDown     = (mods_depressed & (1u << 3)) != 0;
    w->mSuperDown   = (mods_depressed & (1u << 6)) != 0;
}

void WaylandWindow::keyboard_repeat_info(void *data,
                                         struct wl_keyboard * /*keyboard*/,
                                         int32_t rate,
                                         int32_t delay)
{
    // rate is chars/sec; rate == 0 means user disabled key repeat in their
    // compositor settings. delay is ms before the first repeat fires.
    auto *w         = static_cast<WaylandWindow *>(data);
    w->mRepeatRate  = rate;
    w->mRepeatDelay = delay;
}

const struct wl_keyboard_listener WaylandWindow::keyboard_listener = {
    .keymap      = keyboard_keymap,
    .enter       = keyboard_enter,
    .leave       = keyboard_leave,
    .key         = keyboard_key,
    .modifiers   = keyboard_modifiers,
    .repeat_info = keyboard_repeat_info,
};

void WaylandWindow::pointer_enter(void *data,
                                  struct wl_pointer * /*pointer*/,
                                  uint32_t /*serial*/,
                                  struct wl_surface * /*surface*/,
                                  wl_fixed_t x,
                                  wl_fixed_t y)
{
    auto *w      = static_cast<WaylandWindow *>(data);
    w->mPointerX = wl_fixed_to_int(x);
    w->mPointerY = wl_fixed_to_int(y);
    Event event{};
    event.Type = Event::EVENT_MOUSE_ENTERED;
    w->pushEvent(std::move(event));
}

void WaylandWindow::pointer_leave(void *data,
                                  struct wl_pointer * /*pointer*/,
                                  uint32_t /*serial*/,
                                  struct wl_surface * /*surface*/)
{
    auto *w = static_cast<WaylandWindow *>(data);
    Event event{};
    event.Type = Event::EVENT_MOUSE_LEFT;
    w->pushEvent(std::move(event));
}

void WaylandWindow::pointer_motion(void *data,
                                   struct wl_pointer * /*pointer*/,
                                   uint32_t /*time*/,
                                   wl_fixed_t x,
                                   wl_fixed_t y)
{
    auto *w      = static_cast<WaylandWindow *>(data);
    w->mPointerX = wl_fixed_to_int(x);
    w->mPointerY = wl_fixed_to_int(y);
    Event event{};
    event.Type        = Event::EVENT_MOUSE_MOVED;
    event.MouseMove.X = w->mPointerX;
    event.MouseMove.Y = w->mPointerY;
    w->pushEvent(std::move(event));
}

void WaylandWindow::pointer_button(void *data,
                                   struct wl_pointer * /*pointer*/,
                                   uint32_t /*serial*/,
                                   uint32_t /*time*/,
                                   uint32_t button,
                                   uint32_t state)
{
    auto *w = static_cast<WaylandWindow *>(data);
    Event event{};
    event.Type = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? Event::EVENT_MOUSE_BUTTON_PRESSED
                                                            : Event::EVENT_MOUSE_BUTTON_RELEASED;
    event.MouseButton.Button = LinuxButtonToMouseButton(button);
    event.MouseButton.X      = w->mPointerX;
    event.MouseButton.Y      = w->mPointerY;
    w->pushEvent(std::move(event));
}

void WaylandWindow::pointer_axis(void *data,
                                 struct wl_pointer * /*pointer*/,
                                 uint32_t /*time*/,
                                 uint32_t axis,
                                 wl_fixed_t value)
{
    // Compositors typically send 10.0 per discrete vertical wheel notch.
    // Normalize to +/-1 to match X11's Button4/5 and Win32's WHEEL_DELTA
    // semantics. Horizontal axis is ignored -- Event::MouseWheelEvent has no
    // horizontal field.
    if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL)
    {
        return;
    }
    auto *w        = static_cast<WaylandWindow *>(data);
    const double v = wl_fixed_to_double(value);
    if (v == 0.0)
    {
        return;
    }
    Event event{};
    event.Type             = Event::EVENT_MOUSE_WHEEL_MOVED;
    event.MouseWheel.Delta = (v < 0.0) ? 1 : -1;  // wayland: positive = scroll down
    w->pushEvent(std::move(event));
}

void WaylandWindow::pointer_frame(void * /*data*/, struct wl_pointer * /*pointer*/) {}
void WaylandWindow::pointer_axis_source(void * /*data*/,
                                        struct wl_pointer * /*pointer*/,
                                        uint32_t /*source*/)
{}
void WaylandWindow::pointer_axis_stop(void * /*data*/,
                                      struct wl_pointer * /*pointer*/,
                                      uint32_t /*time*/,
                                      uint32_t /*axis*/)
{}
void WaylandWindow::pointer_axis_discrete(void * /*data*/,
                                          struct wl_pointer * /*pointer*/,
                                          uint32_t /*axis*/,
                                          int32_t /*discrete*/)
{}

const struct wl_pointer_listener WaylandWindow::pointer_listener = {
    .enter         = pointer_enter,
    .leave         = pointer_leave,
    .motion        = pointer_motion,
    .button        = pointer_button,
    .axis          = pointer_axis,
    .frame         = pointer_frame,
    .axis_source   = pointer_axis_source,
    .axis_stop     = pointer_axis_stop,
    .axis_discrete = pointer_axis_discrete,
    // v8+ events. We bind seat at v5, so the compositor will never send these,
    // but the listener struct requires every field.
    .axis_value120           = nullptr,
    .axis_relative_direction = nullptr,
#ifdef WL_POINTER_WARP_SINCE_VERSION
    .warp = nullptr,
#endif
};

bool IsWaylandWindowAvailable()
{
    if (!gDisplay)
    {
        wl_display *display = wl_display_connect(nullptr);
        if (!display)
        {
            return false;
        }
        wl_display_flush(display);
        wl_display_disconnect(display);
    }
    return true;
}

OSWindow *CreateWaylandWindow(void *nativeDisplay)
{
    return new WaylandWindow(nativeDisplay);
}
