// Copyright (C) 2018 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 "GLSnapshotTesting.h"

#include "base/PathUtils.h"
#include "base/StdioStream.h"
#include "base/System.h"
#include "base/testing/TestSystem.h"
#include "snapshot/TextureLoader.h"
#include "snapshot/TextureSaver.h"

#include "GLTestUtils.h"
#include "OpenGLTestContext.h"

#include <gtest/gtest.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES3/gl31.h>

namespace emugl {

using android::base::StdioStream;
using android::snapshot::TextureLoader;
using android::snapshot::TextureSaver;

std::string describeGlEnum(GLenum enumValue) {
    std::ostringstream description;
    description << "0x" << std::hex << enumValue
                << " (" << getEnumString(enumValue) << ")";
    return description.str();
}

template <class T>
testing::AssertionResult compareValue(T expected,
                                      T actual,
                                      const std::string& description) {
    if (expected != actual) {
        return testing::AssertionFailure()
               << description << "\n\tvalue was:\t"
               << testing::PrintToString(actual) << "\n\t expected:\t"
               << testing::PrintToString(expected) << "\t";
    }
    return testing::AssertionSuccess();
}

template testing::AssertionResult compareValue<GLboolean>(GLboolean,
                                                          GLboolean,
                                                          const std::string&);
template testing::AssertionResult compareValue<GLint>(GLint,
                                                      GLint,
                                                      const std::string&);
template testing::AssertionResult compareValue<GLfloat>(GLfloat,
                                                        GLfloat,
                                                        const std::string&);

testing::AssertionResult compareGlobalGlBoolean(const GLESv2Dispatch* gl,
                                                GLenum name,
                                                GLboolean expected) {
    GLboolean current;
    gl->glGetBooleanv(name, &current);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareValue<GLboolean>(expected, current,
                                   "GL global boolean mismatch for parameter " +
                                           describeGlEnum(name) + ":");
}

testing::AssertionResult compareGlobalGlInt(const GLESv2Dispatch* gl,
                                            GLenum name,
                                            GLint expected) {
    GLint current;
    gl->glGetIntegerv(name, &current);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareValue<GLint>(expected, current,
                               "GL global int mismatch for parameter " +
                                       describeGlEnum(name) + ":");
}

testing::AssertionResult compareGlobalGlInt_i(const GLESv2Dispatch* gl,
                                              GLenum name,
                                              GLuint index,
                                              GLint expected) {
    GLint current;
    gl->glGetIntegeri_v(name, index, &current);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareValue<GLint>(expected, current,
                               "GL global int_i mismatch for parameter " +
                                       describeGlEnum(name) + ":" + std::to_string(index));

}

testing::AssertionResult compareGlobalGlFloat(const GLESv2Dispatch* gl,
                                              GLenum name,
                                              GLfloat expected) {
    GLfloat current;
    gl->glGetFloatv(name, &current);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareValue<GLfloat>(expected, current,
                                 "GL global float mismatch for parameter " +
                                         describeGlEnum(name) + ":");
}

template <class T>
testing::AssertionResult compareVector(const std::vector<T>& expected,
                                       const std::vector<T>& actual,
                                       const std::string& description) {
    std::stringstream message;
    if (expected.size() != actual.size()) {
        message << "    (!) sizes do not match (actual " << actual.size()
                << ", expected " << expected.size() << ")\n";
    }

    int mismatches = 0;
    for (int i = 0; i < expected.size(); i++) {
        if (i >= actual.size()) {
            if (mismatches < 10) {
                mismatches++;
                message << "    no match for:\t"
                        << testing::PrintToString(expected[i]) << "\n";
            } else {
                mismatches += expected.size() - i;
                message << "\n    nothing can match remaining elements.\n";
                break;
            }
        } else if (expected[i] != actual[i]) {
            mismatches++;
            if (mismatches < 15) {
                message << "    at index " << i << ":\n\tvalue was:\t"
                        << testing::PrintToString(actual[i])
                        << "\n\t expected:\t"
                        << testing::PrintToString(expected[i]) << "\n";
            } else if (mismatches == 15) {
                message << "    ... and indices " << i;
            } else if (mismatches < 50) {
                message << ", " << i;
            } else if (mismatches == 50) {
                message << ", etc...";
            }
        }
    }
    if (mismatches > 0) {
        return testing::AssertionFailure()
               << description << " had " << mismatches << " mismatches.\n"
               << "  expected: " << testing::PrintToString(expected) << "\n"
               << "    actual: " << testing::PrintToString(actual) << "\n"
               << message.str() << "  \n";
    }
    return testing::AssertionSuccess();
}

template testing::AssertionResult compareVector<GLboolean>(
        const std::vector<GLboolean>&,
        const std::vector<GLboolean>&,
        const std::string&);
template testing::AssertionResult compareVector<GLint>(
        const std::vector<GLint>&,
        const std::vector<GLint>&,
        const std::string&);
template testing::AssertionResult compareVector<GLfloat>(
        const std::vector<GLfloat>&,
        const std::vector<GLfloat>&,
        const std::string&);

testing::AssertionResult compareGlobalGlBooleanv(
        const GLESv2Dispatch* gl,
        GLenum name,
        const std::vector<GLboolean>& expected,
        GLuint size) {
    std::vector<GLboolean> current;
    current.resize(std::max(size, static_cast<GLuint>(expected.size())));
    gl->glGetBooleanv(name, &current[0]);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareVector<GLboolean>(
            expected, current,
            "GL global booleanv parameter " + describeGlEnum(name));
}


testing::AssertionResult compareGlobalGlBooleanv_i(
        const GLESv2Dispatch* gl,
        GLenum name,
        GLuint index,
        const std::vector<GLboolean>& expected,
        GLuint size) {
    std::vector<GLboolean> current;
    current.resize(std::max(size, static_cast<GLuint>(expected.size())));
    gl->glGetBooleani_v(name, index,  &current[0]);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareVector<GLboolean>(
            expected, current,
            "GL global booleanv_i parameter " + describeGlEnum(name) + ":" + std::to_string(index) );
}

testing::AssertionResult compareGlobalGlIntv(const GLESv2Dispatch* gl,
                                             GLenum name,
                                             const std::vector<GLint>& expected,
                                             GLuint size) {
    std::vector<GLint> current;
    current.resize(std::max(size, static_cast<GLuint>(expected.size())));
    gl->glGetIntegerv(name, &current[0]);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareVector<GLint>(
            expected, current,
            "GL global intv parameter " + describeGlEnum(name));
}


testing::AssertionResult compareGlobalGlFloatv(
        const GLESv2Dispatch* gl,
        GLenum name,
        const std::vector<GLfloat>& expected,
        GLuint size) {
    std::vector<GLfloat> current;
    current.resize(std::max(size, static_cast<GLuint>(expected.size())));
    gl->glGetFloatv(name, &current[0]);
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    return compareVector<GLfloat>(
            expected, current,
            "GL global floatv parameter " + describeGlEnum(name));
}

void SnapshotTest::SetUp() {
    GLTest::SetUp();
    mTestSystem.getTempRoot()->makeSubDir("Snapshots");
    mSnapshotPath = mTestSystem.getTempRoot()->makeSubPath("Snapshots");
}

void SnapshotTest::saveSnapshot(const std::string streamFile,
                                const std::string textureFile) {
    const EGLDispatch* egl = LazyLoadedEGLDispatch::get();

    std::unique_ptr<StdioStream> m_stream(new StdioStream(
            android_fopen(streamFile.c_str(), "wb"), StdioStream::kOwner));
    auto egl_stream = static_cast<EGLStream>(m_stream.get());
    std::unique_ptr<TextureSaver> m_texture_saver(new TextureSaver(StdioStream(
            android_fopen(textureFile.c_str(), "wb"), StdioStream::kOwner)));

    egl->eglPreSaveContext(m_display, m_context, egl_stream);
    egl->eglSaveAllImages(m_display, egl_stream, &m_texture_saver);

    egl->eglSaveContext(m_display, m_context, egl_stream);

    // Skip saving a bunch of FrameBuffer's fields
    // Skip saving colorbuffers
    // Skip saving window surfaces

    egl->eglSaveConfig(m_display, m_config, egl_stream);

    // Skip saving a bunch of process-owned objects

    egl->eglPostSaveContext(m_display, m_context, egl_stream);

    m_stream->close();
    m_texture_saver->done();
}

void SnapshotTest::loadSnapshot(const std::string streamFile,
                                const std::string textureFile) {
    const EGLDispatch* egl = LazyLoadedEGLDispatch::get();

    std::unique_ptr<StdioStream> m_stream(new StdioStream(
            android_fopen(streamFile.c_str(), "rb"), StdioStream::kOwner));
    auto egl_stream = static_cast<EGLStream>(m_stream.get());
    std::shared_ptr<TextureLoader> m_texture_loader(
            new TextureLoader(StdioStream(android_fopen(textureFile.c_str(), "rb"),
                                          StdioStream::kOwner)));

    egl->eglLoadAllImages(m_display, egl_stream, &m_texture_loader);

    EGLint contextAttribs[5] = {EGL_CONTEXT_CLIENT_VERSION, 3,
                                EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE};

    m_context = egl->eglLoadContext(m_display, &contextAttribs[0], egl_stream);
    m_config = egl->eglLoadConfig(m_display, egl_stream);
    m_surface = pbufferSurface(m_display, m_config, kTestSurfaceSize[0],
                               kTestSurfaceSize[0]);
    egl->eglPostLoadAllImages(m_display, egl_stream);

    m_stream->close();
    m_texture_loader->join();
    egl->eglMakeCurrent(m_display, m_surface, m_surface, m_context);
}

void SnapshotTest::preloadReset() {
    GLTest::TearDown();
    GLTest::SetUp();
}

void SnapshotTest::doSnapshot(std::function<void()> preloadCheck = [] {}) {
    std::string timeStamp =
            std::to_string(android::base::getUnixTimeUs());
    std::string snapshotFile =
            android::base::pj({mSnapshotPath, std::string("snapshot_") + timeStamp + ".snap"});
    std::string textureFile =
            android::base::pj({mSnapshotPath, std::string("textures_") + timeStamp + ".stex"});

    saveSnapshot(snapshotFile, textureFile);

    preloadReset();
    preloadCheck();

    loadSnapshot(snapshotFile, textureFile);

    EXPECT_NE(m_context, EGL_NO_CONTEXT);
    EXPECT_NE(m_surface, EGL_NO_SURFACE);
}

void SnapshotPreserveTest::doCheckedSnapshot() {
    {
        SCOPED_TRACE("during pre-snapshot default state check");
        defaultStateCheck();
        ASSERT_EQ(GL_NO_ERROR, gl->glGetError());
    }
    {
        SCOPED_TRACE("during pre-snapshot state change");
        stateChange();
        ASSERT_EQ(GL_NO_ERROR, gl->glGetError());
    }
    {
        SCOPED_TRACE("during pre-snapshot changed state check");
        changedStateCheck();
    }
    SnapshotTest::doSnapshot([this] {
        SCOPED_TRACE("during post-reset default state check");
        EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
        defaultStateCheck();
    });
    EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    {
        SCOPED_TRACE("during post-snapshot changed state check");
        changedStateCheck();
        EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
    }
}

}  // namespace emugl
