// 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 "ShaderUtils.h"

#include "aemu/base/files/PathUtils.h"
#include "aemu/base/Optional.h"
#include "aemu/base/system/System.h"

#include "OpenGLESDispatch/OpenGLDispatchLoader.h"

#include <fstream>
#include <vector>

#include <fcntl.h>
#include <stdio.h>

using android::base::Optional;
using android::base::pj;

#define DEBUG 0

#if DEBUG
#define D(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);
#else
#define D(fmt,...)
#endif

#define E(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);

namespace gfxstream {

GLuint compileShader(GLenum shaderType, const char* src) {
    auto gl = gl::LazyLoadedGLESv2Dispatch::get();

    GLuint shader = gl->glCreateShader(shaderType);
    gl->glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
    gl->glCompileShader(shader);

    GLint compileStatus;
    gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);

    if (compileStatus != GL_TRUE) {
        GLsizei infoLogLength = 0;
        gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        std::vector<char> infoLog(infoLogLength + 1, 0);
        gl->glGetShaderInfoLog(shader, infoLogLength, nullptr, &infoLog[0]);
        E("fail to compile. infolog: %s", &infoLog[0]);
    }

    return shader;
}

GLint compileAndLinkShaderProgram(const char* vshaderSrc, const char* fshaderSrc) {
    auto gl = gl::LazyLoadedGLESv2Dispatch::get();

    GLuint vshader = compileShader(GL_VERTEX_SHADER, vshaderSrc);
    GLuint fshader = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);

    GLuint program = gl->glCreateProgram();
    gl->glAttachShader(program, vshader);
    gl->glAttachShader(program, fshader);
    gl->glLinkProgram(program);

    GLint linkStatus;
    gl->glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);

    gl->glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

    if (linkStatus != GL_TRUE) {
        GLsizei infoLogLength = 0;
        gl->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        std::vector<char> infoLog(infoLogLength + 1, 0);
        gl->glGetProgramInfoLog(program, infoLogLength, nullptr, &infoLog[0]);

        E("failed to link. infolog: %s", &infoLog[0]);
    }

    return program;
}

// static Optional<std::string> getSpirvCompilerPath() {
// #ifdef _WIN32
//     std::string programName = "glslangValidator.exe";
// #else
//     std::string programName = "glslangValidator";
// #endif
//
//     auto programDirRelativePath =
//         pj(android::base::getProgramDirectory(),
//            "lib64", "vulkan", "tools", programName);
//
//     if (path_exists(programDirRelativePath.c_str())) {
//         return programDirRelativePath;
//     }
//
//     auto launcherDirRelativePath =
//         pj(android::base::getLauncherDirectory(),
//            "lib64", "vulkan", programName);
//
//     if (path_exists(launcherDirRelativePath.c_str())) {
//         return launcherDirRelativePath;
//     }
//
//     E("spirv compiler does not exist");
//     return {};
// }

// Optional<std::string> compileSpirvFromGLSL(const std::string& shaderType,
//                                            const std::string& src) {
//     auto spvCompilerPath = getSpirvCompilerPath();
//
//     if (!spvCompilerPath) return {};
//
//     const auto glslFile = android::base::makeCustomScopedPtr(
//             tempfile_create(), tempfile_unref_and_close_file);
//
//     const auto spvFile = android::base::makeCustomScopedPtr(
//             tempfile_create(), tempfile_unref_and_close_file);
//
//     auto glslPath = tempfile_path(glslFile.get());
//     auto spvPath = tempfile_path(spvFile.get());
//
//     auto glslFd = android::base::ScopedFd(open(glslPath, O_RDWR));
//     if (!glslFd.valid()) { return {}; }
//
//     android::writeStringToFile(glslFd.get(), src);
//     glslFd.close();
//
//     std::vector<std::string> args =
//         { *spvCompilerPath, glslPath, "-V", "-S", shaderType, "-o", spvPath };
//
//     auto runRes = System::get()->runCommandWithResult(args);
//
//     if (!runRes) {
//         E("failed to compile SPIRV from GLSL. args: %s %s -V -S %s -o %s",
//           spvCompilerPath->c_str(), glslPath, shaderType.c_str(), spvPath);
//         return {};
//     }
//
//     D("Result of compiling SPIRV from GLSL. res: %s args: %s %s -V -S %s -o %s",
//       runRes->c_str(), spvCompilerPath->c_str(), glslPath, shaderType.c_str(),
//       spvPath);
//
//     auto res = android::readFileIntoString(spvPath);
//
//     if (res) {
//         D("got %zu bytes:", res->size());
//     } else {
//         E("failed to read SPIRV file %s into string", spvPath);
//     }
//
//     return res;
// }
//
// Optional<std::vector<char> > readSpirv(const char* path) {
//     std::ifstream in(path, std::ios::ate | std::ios::binary);
//
//     if (!in) return {};
//
//     size_t fileSize = (size_t)in.tellg();
//     std::vector<char> buffer(fileSize);
//
//     in.seekg(0);
//     in.read(buffer.data(), fileSize);
//
//     return buffer;
// }

}  // namespace gfxstream
