#include <string>

#include <GL/glew.h>

#include <glshader.hpp>
#include <gltest.hpp>


GLTEST(2, 0, 640, 480, glshader)
{
    gltest_root("assets/tests");
    Shader::root("assets/shaders");

    // Create.
    GLTEST_EXPECT_EXCEPTION(false,
        Shader({"tests/create_noextension"}),
        "Failed to infer type of shader 'tests/create_noextension' of shader program 'tests/create_noextension'; "
        "no file extension."
    )
    GLTEST_EXPECT_EXCEPTION(false,
        Shader({"tests/create.unknownextension"}),
        "Failed to infer type of shader 'tests/create.unknownextension' of shader program 'tests/create.unknownextension'; "
        "unknown file extension 'unknownextension'."
    )
    GLTEST_EXPECT_EXCEPTION(true,
        Shader({"tests/create_nonexistent.vert"}),
        "Failed to source shader 'tests/create_nonexistent.vert' of shader program 'tests/create_nonexistent.vert'; "
        "could not open file 'assets/shaders/tests/create_nonexistent.vert':\n"
        "No such file or directory"
    )
    GLTEST_EXPECT_EXCEPTION(true,
        Shader({"tests/create_bad_compile.vert"}),
        "Failed to compile shader 'tests/create_bad_compile.vert' of shader program 'tests/create_bad_compile.vert':\n"
        "0:4(5): error: main() must return void\n"
    )
    GLTEST_EXPECT_EXCEPTION(true,
        Shader({"tests/create_bad_link.vert"}),
        "Failed to link shader program 'tests/create_bad_link.vert':\n"
        "error: vertex shader does not write to `gl_Position'. \n"
    )

    // Validate.
    GLTEST_EXPECT_EXCEPTION(true,
        Shader({"tests/validate_bad_samplers.vert"}).validate(),
        "Failed to validate shader program 'tests/validate_bad_samplers.vert':\n"
        "active samplers with a different type refer to the same texture image unit"
    )

    auto all = Shader({
        "tests/all.vert",
        "tests/all.frag",
    });

    all
        .validate();

    constexpr auto size = 0.5F;
    glBegin(GL_TRIANGLE_STRIP);
    glVertex3f(-size, -size, 0.0F);
    glVertex3f(-size, +size, 0.0F);
    glVertex3f(+size, -size, 0.0F);
    glVertex3f(+size, +size, 0.0F);
    glEnd();

    GLTEST_EXPECT_FRAME("frame.data")
}