// 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 "aemu/base/files/PathUtils.h"
#include "aemu/base/files/StdioStream.h"
#include "aemu/base/system/System.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 gfxstream {
namespace gl {

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<EGLStreamKHR>(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<EGLStreamKHR>(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 gl
}  // namespace gfxstream
