/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <pthread.h>
#include <stdlib.h>
#include <string.h>

static EGLDisplay gDisplay = (EGLDisplay) 1;
static EGLSyncKHR gFence = (EGLSyncKHR) 1;

typedef struct {
    EGLSurface surface;
    EGLContext context;
} ThreadState;

static pthread_key_t ThreadStateKey;
static pthread_once_t ThreadStateSetupOnce = PTHREAD_ONCE_INIT;

static void destroyThreadState(void* state) {
    free(state);
}

static void makeThreadState() {
    pthread_key_create(&ThreadStateKey, destroyThreadState);
}

ThreadState* getThreadState() {
    ThreadState* ptr;
    pthread_once(&ThreadStateSetupOnce, makeThreadState);
    if ((ptr = (ThreadState*) pthread_getspecific(ThreadStateKey)) == NULL) {
        ptr = (ThreadState*) calloc(1, sizeof(ThreadState));
        ptr->context = EGL_NO_CONTEXT;
        ptr->surface = EGL_NO_SURFACE;
        pthread_setspecific(ThreadStateKey, ptr);
    }
    return ptr;
}

EGLint eglGetError(void) {
    return EGL_SUCCESS;
}

EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
    return gDisplay;
}

EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
    return EGL_TRUE;
}

EGLBoolean eglTerminate(EGLDisplay dpy) {
    return EGL_TRUE;
}

const char * eglQueryString(EGLDisplay dpy, EGLint name) {
    if (name == EGL_EXTENSIONS) {
        return "EGL_KHR_swap_buffers_with_damage";
    }
    return "";
}

EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
               EGLConfig *configs, EGLint config_size,
               EGLint *num_config) {
    memset(configs, 9, sizeof(EGLConfig) * config_size);
    *num_config = config_size;
    return EGL_TRUE;
}

EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                  EGLNativeWindowType win,
                  const EGLint *attrib_list) {
    return (EGLSurface) malloc(sizeof(void*));
}

EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                   const EGLint *attrib_list) {
    return (EGLSurface) malloc(sizeof(void*));
}

EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
    free(surface);
    return EGL_TRUE;
}

EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
               EGLint attribute, EGLint *value) {
    *value = 1000;
    return EGL_TRUE;
}

EGLBoolean eglReleaseThread(void) {
    return EGL_TRUE;
}

EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
                EGLint attribute, EGLint value) {
    return EGL_TRUE;
}

EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
    return EGL_TRUE;
}

EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
                EGLContext share_context,
                const EGLint *attrib_list) {
    return (EGLContext) malloc(sizeof(void*));
}
EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
    free(ctx);
    return EGL_TRUE;
}

EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
              EGLSurface read, EGLContext ctx) {
    ThreadState* state = getThreadState();
    state->surface = draw;
    state->context = ctx;
    return EGL_TRUE;
}

EGLContext eglGetCurrentContext(void) {
    return getThreadState()->context;
}

EGLSurface eglGetCurrentSurface(EGLint readdraw) {
    return getThreadState()->surface;
}

EGLDisplay eglGetCurrentDisplay(void) {
    return gDisplay;
}

EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
    return EGL_TRUE;
}

EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint rectCount) {
    return EGL_TRUE;
}

EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) {
    return (EGLImageKHR) malloc(sizeof(EGLImageKHR));
}

EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) {
    return gFence;
}

EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
    return EGL_TRUE;
}

EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
    return EGL_CONDITION_SATISFIED_KHR;
}

EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
    free(image);
    return EGL_TRUE;
}

void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {}
