#include "qemu/osdep.h"
#include <glob.h>
#include <dirent.h>

#include "config-host.h"
#include "ui/egl-helpers.h"

EGLDisplay *qemu_egl_display;
EGLConfig qemu_egl_config;

/* ---------------------------------------------------------------------- */

static bool egl_gles;
static int egl_debug;

#define egl_dbg(_x ...)                          \
    do {                                         \
        if (egl_debug) {                         \
            fprintf(stderr, "egl: " _x);         \
        }                                        \
    } while (0);

/* ---------------------------------------------------------------------- */

#ifdef CONFIG_OPENGL_DMABUF

int qemu_egl_rn_fd;
struct gbm_device *qemu_egl_rn_gbm_dev;
EGLContext qemu_egl_rn_ctx;

int qemu_egl_rendernode_open(void)
{
    DIR *dir;
    struct dirent *e;
    int r, fd;
    char *p;

    dir = opendir("/dev/dri");
    if (!dir) {
        return -1;
    }

    fd = -1;
    while ((e = readdir(dir))) {
        if (e->d_type != DT_CHR) {
            continue;
        }

        if (strncmp(e->d_name, "renderD", 7)) {
            continue;
        }

        r = asprintf(&p, "/dev/dri/%s", e->d_name);
        if (r < 0) {
            return -1;
        }

        r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
        if (r < 0) {
            free(p);
            continue;
        }
        fd = r;
        free(p);
        break;
    }

    closedir(dir);
    if (fd < 0) {
        return -1;
    }
    return fd;
}

int egl_rendernode_init(void)
{
    qemu_egl_rn_fd = -1;

    qemu_egl_rn_fd = qemu_egl_rendernode_open();
    if (qemu_egl_rn_fd == -1) {
        fprintf(stderr, "egl: no drm render node available\n");
        goto err;
    }

    qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd);
    if (!qemu_egl_rn_gbm_dev) {
        fprintf(stderr, "egl: gbm_create_device failed\n");
        goto err;
    }

    qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, false);

    if (!epoxy_has_egl_extension(qemu_egl_display,
                                 "EGL_KHR_surfaceless_context")) {
        fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n");
        goto err;
    }
    if (!epoxy_has_egl_extension(qemu_egl_display,
                                 "EGL_MESA_image_dma_buf_export")) {
        fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n");
        goto err;
    }

    qemu_egl_rn_ctx = qemu_egl_init_ctx();
    if (!qemu_egl_rn_ctx) {
        fprintf(stderr, "egl: egl_init_ctx failed\n");
        goto err;
    }

    return 0;

err:
    if (qemu_egl_rn_gbm_dev) {
        gbm_device_destroy(qemu_egl_rn_gbm_dev);
    }
    if (qemu_egl_rn_fd != -1) {
        close(qemu_egl_rn_fd);
    }

    return -1;
}

int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc)
{
    EGLImageKHR image;
    EGLint num_planes, fd;

    image = eglCreateImageKHR(qemu_egl_display, eglGetCurrentContext(),
                              EGL_GL_TEXTURE_2D_KHR,
                              (EGLClientBuffer)(unsigned long)tex_id,
                              NULL);
    if (!image) {
        return -1;
    }

    eglExportDMABUFImageQueryMESA(qemu_egl_display, image, fourcc,
                                  &num_planes, NULL);
    if (num_planes != 1) {
        eglDestroyImageKHR(qemu_egl_display, image);
        return -1;
    }
    eglExportDMABUFImageMESA(qemu_egl_display, image, &fd, stride, NULL);
    eglDestroyImageKHR(qemu_egl_display, image);

    return fd;
}

#endif /* CONFIG_OPENGL_DMABUF */

/* ---------------------------------------------------------------------- */

EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
{
    EGLSurface esurface;
    EGLBoolean b;

    egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
            (unsigned long) win);
    esurface = eglCreateWindowSurface(qemu_egl_display,
                                      qemu_egl_config,
                                      (EGLNativeWindowType)win, NULL);
    if (esurface == EGL_NO_SURFACE) {
        fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
        return NULL;
    }

    b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
    if (b == EGL_FALSE) {
        fprintf(stderr, "egl: eglMakeCurrent failed\n");
        return NULL;
    }

    return esurface;
}

/* ---------------------------------------------------------------------- */

int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
{
    static const EGLint conf_att_gl[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
        EGL_RED_SIZE,   5,
        EGL_GREEN_SIZE, 5,
        EGL_BLUE_SIZE,  5,
        EGL_ALPHA_SIZE, 0,
        EGL_NONE,
    };
    static const EGLint conf_att_gles[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_RED_SIZE,   5,
        EGL_GREEN_SIZE, 5,
        EGL_BLUE_SIZE,  5,
        EGL_ALPHA_SIZE, 0,
        EGL_NONE,
    };
    EGLint major, minor;
    EGLBoolean b;
    EGLint n;

    if (debug) {
        egl_debug = 1;
        setenv("EGL_LOG_LEVEL", "debug", true);
        setenv("LIBGL_DEBUG", "verbose", true);
    }

    egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
    qemu_egl_display = eglGetDisplay(dpy);
    if (qemu_egl_display == EGL_NO_DISPLAY) {
        fprintf(stderr, "egl: eglGetDisplay failed\n");
        return -1;
    }

    egl_dbg("eglInitialize ...\n");
    b = eglInitialize(qemu_egl_display, &major, &minor);
    if (b == EGL_FALSE) {
        fprintf(stderr, "egl: eglInitialize failed\n");
        return -1;
    }

    egl_dbg("eglBindAPI ...\n");
    b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
    if (b == EGL_FALSE) {
        fprintf(stderr, "egl: eglBindAPI failed\n");
        return -1;
    }

    egl_dbg("eglChooseConfig ...\n");
    b = eglChooseConfig(qemu_egl_display,
                        gles ? conf_att_gles : conf_att_gl,
                        &qemu_egl_config, 1, &n);
    if (b == EGL_FALSE || n != 1) {
        fprintf(stderr, "egl: eglChooseConfig failed\n");
        return -1;
    }

    egl_gles = gles;
    return 0;
}

EGLContext qemu_egl_init_ctx(void)
{
    static const EGLint ctx_att_gl[] = {
        EGL_NONE
    };
    static const EGLint ctx_att_gles[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    EGLContext ectx;
    EGLBoolean b;

    egl_dbg("eglCreateContext ...\n");
    ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
                            egl_gles ? ctx_att_gles : ctx_att_gl);
    if (ectx == EGL_NO_CONTEXT) {
        fprintf(stderr, "egl: eglCreateContext failed\n");
        return NULL;
    }

    b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
    if (b == EGL_FALSE) {
        fprintf(stderr, "egl: eglMakeCurrent failed\n");
        return NULL;
    }

    return ectx;
}
