//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ShCompile_test.cpp
//   Test the sh::Compile interface with different parameters.
//

#include <clocale>
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h"
#include "common/angleutils.h"
#include "common/platform.h"
#include "gtest/gtest.h"

class ShCompileTest : public testing::Test
{
  public:
    ShCompileTest() {}

  protected:
    void SetUp() override
    {
        sh::InitBuiltInResources(&mResources);
        mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC,
                                          SH_GLSL_150_CORE_OUTPUT, &mResources);
        ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
    }

    void TearDown() override
    {
        if (mCompiler)
        {
            sh::Destruct(mCompiler);
            mCompiler = nullptr;
        }
    }

    void testCompile(const char **shaderStrings, int stringCount, bool expectation)
    {
        ShCompileOptions options    = {};
        options.objectCode          = true;
        options.initOutputVariables = true;

        bool success                  = sh::Compile(mCompiler, shaderStrings, stringCount, options);
        const std::string &compileLog = sh::GetInfoLog(mCompiler);
        EXPECT_EQ(expectation, success) << compileLog;
    }

    ShBuiltInResources mResources;

    class [[nodiscard]] ScopedRestoreDefaultLocale : angle::NonCopyable
    {
      public:
        ScopedRestoreDefaultLocale();
        ~ScopedRestoreDefaultLocale();

      private:
        std::locale defaultLocale;
    };

  public:
    ShHandle mCompiler;
};

ShCompileTest::ScopedRestoreDefaultLocale::ScopedRestoreDefaultLocale()
{
    defaultLocale = std::locale();
}

ShCompileTest::ScopedRestoreDefaultLocale::~ScopedRestoreDefaultLocale()
{
    std::locale::global(defaultLocale);
}

class ShCompileComputeTest : public ShCompileTest
{
  public:
    ShCompileComputeTest() {}

  protected:
    void SetUp() override
    {
        sh::InitBuiltInResources(&mResources);
        mCompiler = sh::ConstructCompiler(GL_COMPUTE_SHADER, SH_GLES3_1_SPEC,
                                          SH_GLSL_150_CORE_OUTPUT, &mResources);
        ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
    }
};

// Test calling sh::Compile with compute shader source string.
TEST_F(ShCompileComputeTest, ComputeShaderString)
{
    constexpr char kComputeShaderString[] =
        R"(#version 310 es
        layout(local_size_x=1) in;
        void main()
        {
        })";

    const char *shaderStrings[] = {kComputeShaderString};

    testCompile(shaderStrings, 1, true);
}

// Test calling sh::Compile with more than one shader source string.
TEST_F(ShCompileTest, MultipleShaderStrings)
{
    const std::string &shaderString1 =
        "precision mediump float;\n"
        "void main() {\n";
    const std::string &shaderString2 =
        "    gl_FragColor = vec4(0.0);\n"
        "}";

    const char *shaderStrings[] = {shaderString1.c_str(), shaderString2.c_str()};

    testCompile(shaderStrings, 2, true);
}

// Test calling sh::Compile with a tokens split into different shader source strings.
TEST_F(ShCompileTest, TokensSplitInShaderStrings)
{
    const std::string &shaderString1 =
        "precision mediump float;\n"
        "void ma";
    const std::string &shaderString2 =
        "in() {\n"
        "#i";
    const std::string &shaderString3 =
        "f 1\n"
        "    gl_FragColor = vec4(0.0);\n"
        "#endif\n"
        "}";

    const char *shaderStrings[] = {shaderString1.c_str(), shaderString2.c_str(),
                                   shaderString3.c_str()};

    testCompile(shaderStrings, 3, true);
}

// Parsing floats in shaders can run afoul of locale settings.
// Eg. in de_DE, `strtof("1.5")` will yield `1.0f`. (It's expecting "1.5")
TEST_F(ShCompileTest, DecimalSepLocale)
{
    // Locale names are platform dependent, add platform-specific names of locales to be tested here
    const std::string availableLocales[] = {
        "de_DE",
        "de-DE",
        "de_DE.UTF-8",
        "de_DE.ISO8859-1",
        "de_DE.ISO8859-15",
        "de_DE@euro",
        "de_DE.88591",
        "de_DE.88591.en",
        "de_DE.iso88591",
        "de_DE.ISO-8859-1",
        "de_DE.ISO_8859-1",
        "de_DE.iso885915",
        "de_DE.ISO-8859-15",
        "de_DE.ISO_8859-15",
        "de_DE.8859-15",
        "de_DE.8859-15@euro",
#if !defined(_WIN32)
        // TODO(https://crbug.com/972372): Add this test back on Windows once the
        // CRT no longer throws on code page sections ('ISO-8859-15@euro') that
        // are >= 16 characters long.
        "de_DE.ISO-8859-15@euro",
#endif
        "de_DE.UTF-8@euro",
        "de_DE.utf8",
        "German_germany",
        "German_Germany",
        "German_Germany.1252",
        "German_Germany.UTF-8",
        "German",
        // One ubuntu tester doesn't have a german locale, but da_DK.utf8 has similar float
        // representation
        "da_DK.utf8"
    };

    const auto localeExists = [](const std::string name) {
        return bool(setlocale(LC_ALL, name.c_str()));
    };

    const char kSource[] = R"(
    void main()
    {
        gl_FragColor = vec4(1.5);
    })";
    const char *parts[]  = {kSource};

    // Ensure the locale is reset after the test runs.
    ScopedRestoreDefaultLocale restoreLocale;

    for (const std::string &locale : availableLocales)
    {
        // If the locale doesn't exist on the testing platform, the locale constructor will fail,
        // throwing an exception
        // We use setlocale() (through localeExists) to test whether a locale
        // exists before calling the locale constructor
        if (localeExists(locale))
        {
            std::locale localizedLoc(locale);

            ShCompileOptions compileOptions = {};
            compileOptions.objectCode       = true;

            // std::locale::global() must be used instead of setlocale() to affect new streams'
            // default locale
            std::locale::global(std::locale::classic());
            sh::Compile(mCompiler, parts, 1, compileOptions);
            std::string referenceOut = sh::GetObjectCode(mCompiler);
            EXPECT_NE(referenceOut.find("1.5"), std::string::npos)
                << "float formatted incorrectly with classic locale";

            sh::ClearResults(mCompiler);

            std::locale::global(localizedLoc);
            sh::Compile(mCompiler, parts, 1, compileOptions);
            std::string localizedOut = sh::GetObjectCode(mCompiler);
            EXPECT_NE(localizedOut.find("1.5"), std::string::npos)
                << "float formatted incorrectly with locale (" << localizedLoc.name() << ") set";

            ASSERT_EQ(referenceOut, localizedOut)
                << "different output with locale (" << localizedLoc.name() << ") set";
        }
    }
}
