/*
 * Copyright 2013 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 "GLTest.h"

#include <gui/Surface.h>

#include <GLES2/gl2.h>

namespace android {

static int abs(int value) {
    return value > 0 ? value : -value;
}

void GLTest::SetUp() {
    const ::testing::TestInfo* const testInfo =
        ::testing::UnitTest::GetInstance()->current_test_info();
    ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());

    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);

    EGLint majorVersion;
    EGLint minorVersion;
    EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    RecordProperty("EglVersionMajor", majorVersion);
    RecordProperty("EglVersionMinor", minorVersion);

    EGLint numConfigs = 0;
    EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig, 1,
            &numConfigs));
    ASSERT_EQ(EGL_SUCCESS, eglGetError());

    char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
    if (displaySecsEnv != NULL) {
        mDisplaySecs = atoi(displaySecsEnv);
        if (mDisplaySecs < 0) {
            mDisplaySecs = 0;
        }
    } else {
        mDisplaySecs = 0;
    }

    if (mDisplaySecs > 0) {
        mComposerClient = new SurfaceComposerClient;
        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());

        mSurfaceControl = mComposerClient->createSurface(
                String8("Test Surface"), getSurfaceWidth(), getSurfaceHeight(),
                PIXEL_FORMAT_RGB_888, 0);

        ASSERT_TRUE(mSurfaceControl != NULL);
        ASSERT_TRUE(mSurfaceControl->isValid());

        SurfaceComposerClient::openGlobalTransaction();
        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
        SurfaceComposerClient::closeGlobalTransaction();

        sp<ANativeWindow> window = mSurfaceControl->getSurface();
        mEglSurface = createWindowSurface(mEglDisplay, mGlConfig, window);
    } else {
        EGLint pbufferAttribs[] = {
            EGL_WIDTH, getSurfaceWidth(),
            EGL_HEIGHT, getSurfaceHeight(),
            EGL_NONE };

        mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
                pbufferAttribs);
    }
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    ASSERT_NE(EGL_NO_SURFACE, mEglSurface);

    mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
            getContextAttribs());
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    ASSERT_NE(EGL_NO_CONTEXT, mEglContext);

    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
            mEglContext));
    ASSERT_EQ(EGL_SUCCESS, eglGetError());

    EGLint w, h;
    EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
    ASSERT_EQ(EGL_SUCCESS, eglGetError());
    RecordProperty("EglSurfaceWidth", w);
    RecordProperty("EglSurfaceHeight", h);

    glViewport(0, 0, w, h);
    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
}

void GLTest::TearDown() {
    // Display the result
    if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
        eglSwapBuffers(mEglDisplay, mEglSurface);
        sleep(mDisplaySecs);
    }

    if (mComposerClient != NULL) {
        mComposerClient->dispose();
    }
    if (mEglContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEglDisplay, mEglContext);
    }
    if (mEglSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEglDisplay, mEglSurface);
    }
    if (mEglDisplay != EGL_NO_DISPLAY) {
        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
                EGL_NO_CONTEXT);
        eglTerminate(mEglDisplay);
    }
    ASSERT_EQ(EGL_SUCCESS, eglGetError());

    const ::testing::TestInfo* const testInfo =
        ::testing::UnitTest::GetInstance()->current_test_info();
    ALOGV("End test:   %s.%s", testInfo->test_case_name(), testInfo->name());
}

EGLint const* GLTest::getConfigAttribs() {
    static const EGLint sDefaultConfigAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_DEPTH_SIZE, 16,
        EGL_STENCIL_SIZE, 8,
        EGL_NONE };

    return sDefaultConfigAttribs;
}

EGLint const* GLTest::getContextAttribs() {
    static const EGLint sDefaultContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE };

    return sDefaultContextAttribs;
}

EGLint GLTest::getSurfaceWidth() {
    return 512;
}

EGLint GLTest::getSurfaceHeight() {
    return 512;
}

EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config,
                                       sp<ANativeWindow>& window) const {
    return eglCreateWindowSurface(display, config, window.get(), NULL);
}

::testing::AssertionResult GLTest::checkPixel(int x, int y,
        int r, int g, int b, int a, int tolerance) {
    GLubyte pixel[4];
    String8 msg;
    glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
    GLenum err = glGetError();
    if (err != GL_NO_ERROR) {
        msg += String8::format("error reading pixel: %#x", err);
        while ((err = glGetError()) != GL_NO_ERROR) {
            msg += String8::format(", %#x", err);
        }
        return ::testing::AssertionFailure(::testing::Message(msg.string()));
    }
    if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
        msg += String8::format("r(%d isn't %d)", pixel[0], r);
    }
    if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("g(%d isn't %d)", pixel[1], g);
    }
    if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("b(%d isn't %d)", pixel[2], b);
    }
    if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("a(%d isn't %d)", pixel[3], a);
    }
    if (!msg.isEmpty()) {
        return ::testing::AssertionFailure(::testing::Message(msg.string()));
    } else {
        return ::testing::AssertionSuccess();
    }
}

::testing::AssertionResult GLTest::assertRectEq(const Rect &r1, const Rect &r2,
                                                int tolerance) {
    String8 msg;

    if (abs(r1.left - r2.left) > tolerance) {
        msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
    }
    if (abs(r1.top - r2.top) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
    }
    if (abs(r1.right - r2.right) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
    }
    if (abs(r1.bottom - r2.bottom) > tolerance) {
        if (!msg.isEmpty()) {
            msg += " ";
        }
        msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
    }
    if (!msg.isEmpty()) {
        msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
                               r1.left, r1.top, r1.right, r1.bottom,
                               r2.left, r2.top, r2.right, r2.bottom);
        fprintf(stderr, "assertRectEq: %s\n", msg.string());
        return ::testing::AssertionFailure(::testing::Message(msg.string()));
    } else {
        return ::testing::AssertionSuccess();
    }
}

void GLTest::loadShader(GLenum shaderType, const char* pSource,
        GLuint* outShader) {
    GLuint shader = glCreateShader(shaderType);
    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    if (shader) {
        glShaderSource(shader, 1, &pSource, NULL);
        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
        glCompileShader(shader);
        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
        GLint compiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
        if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
            if (infoLen) {
                char* buf = (char*) malloc(infoLen);
                if (buf) {
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
                    printf("Shader compile log:\n%s\n", buf);
                    free(buf);
                    FAIL();
                }
            } else {
                char* buf = (char*) malloc(0x1000);
                if (buf) {
                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
                    printf("Shader compile log:\n%s\n", buf);
                    free(buf);
                    FAIL();
                }
            }
            glDeleteShader(shader);
            shader = 0;
        }
    }
    ASSERT_TRUE(shader != 0);
    *outShader = shader;
}

void GLTest::createProgram(const char* pVertexSource,
        const char* pFragmentSource, GLuint* outPgm) {
    GLuint vertexShader, fragmentShader;
    {
        SCOPED_TRACE("compiling vertex shader");
        ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
                &vertexShader));
    }
    {
        SCOPED_TRACE("compiling fragment shader");
        ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
                &fragmentShader));
    }

    GLuint program = glCreateProgram();
    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
    if (program) {
        glAttachShader(program, vertexShader);
        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
        glAttachShader(program, fragmentShader);
        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
        glLinkProgram(program);
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char* buf = (char*) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(program, bufLength, NULL, buf);
                    printf("Program link log:\n%s\n", buf);
                    free(buf);
                    FAIL();
                }
            }
            glDeleteProgram(program);
            program = 0;
        }
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    ASSERT_TRUE(program != 0);
    *outPgm = program;
}

} // namespace android
