// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <GLES2/gl2.h>

#include "gpu/command_buffer/service/shader_translator.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gpu {
namespace gles2 {

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

  virtual ~ShaderTranslatorTest() {
  }

 protected:
  virtual void SetUp() {
    ShBuiltInResources resources;
    ShInitBuiltInResources(&resources);
    resources.MaxExpressionComplexity = 32;
    resources.MaxCallStackDepth = 32;

    vertex_translator_ = new ShaderTranslator();
    fragment_translator_ = new ShaderTranslator();

    ASSERT_TRUE(vertex_translator_->Init(
        GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
        ShaderTranslatorInterface::kGlsl,
        SH_EMULATE_BUILT_IN_FUNCTIONS));
    ASSERT_TRUE(fragment_translator_->Init(
        GL_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
        ShaderTranslatorInterface::kGlsl,
        static_cast<ShCompileOptions>(0)));
  }
  virtual void TearDown() {
    vertex_translator_ = NULL;
    fragment_translator_ = NULL;
  }

  scoped_refptr<ShaderTranslator> vertex_translator_;
  scoped_refptr<ShaderTranslator> fragment_translator_;
};

TEST_F(ShaderTranslatorTest, ValidVertexShader) {
  const char* shader =
      "void main() {\n"
      "  gl_Position = vec4(1.0);\n"
      "}";

  // A valid shader should be successfully translated.
  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_TRUE(vertex_translator_->Translate(shader,
                                            &info_log,
                                            &translated_source,
                                            &attrib_map,
                                            &uniform_map,
                                            &varying_map,
                                            &name_map));
  // Info log must be NULL.
  EXPECT_TRUE(info_log.empty());
  // Translated shader must be valid and non-empty.
  ASSERT_FALSE(translated_source.empty());
  // There should be no attributes, uniforms, varyings.
  EXPECT_TRUE(attrib_map.empty());
  EXPECT_TRUE(uniform_map.empty());
  EXPECT_TRUE(varying_map.empty());
  // There should be no name mapping.
  EXPECT_TRUE(name_map.empty());
}

TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
  const char* bad_shader = "foo-bar";
  const char* good_shader =
      "void main() {\n"
      "  gl_Position = vec4(1.0);\n"
      "}";

  // An invalid shader should fail.
  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_FALSE(vertex_translator_->Translate(bad_shader,
                                             &info_log,
                                             &translated_source,
                                             &attrib_map,
                                             &uniform_map,
                                             &varying_map,
                                             &name_map));
  // Info log must be valid and non-empty.
  ASSERT_FALSE(info_log.empty());
  // Translated shader must be NULL.
  EXPECT_TRUE(translated_source.empty());
  // There should be no attributes, uniforms, varyings, or name mapping.
  EXPECT_TRUE(attrib_map.empty());
  EXPECT_TRUE(uniform_map.empty());
  EXPECT_TRUE(varying_map.empty());
  EXPECT_TRUE(name_map.empty());

  // Try a good shader after bad.
  info_log.clear();
  EXPECT_TRUE(vertex_translator_->Translate(good_shader,
                                            &info_log,
                                            &translated_source,
                                            &attrib_map,
                                            &uniform_map,
                                            &varying_map,
                                            &name_map));
  EXPECT_TRUE(info_log.empty());
  EXPECT_FALSE(translated_source.empty());
}

TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
  const char* shader =
      "void main() {\n"
      "  gl_FragColor = vec4(1.0);\n"
      "}";

  // A valid shader should be successfully translated.
  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_TRUE(fragment_translator_->Translate(shader,
                                              &info_log,
                                              &translated_source,
                                              &attrib_map,
                                              &uniform_map,
                                              &varying_map,
                                              &name_map));
  // Info log must be NULL.
  EXPECT_TRUE(info_log.empty());
  // Translated shader must be valid and non-empty.
  ASSERT_FALSE(translated_source.empty());
  // There should be no attributes, uniforms, varyings, or name mapping.
  EXPECT_TRUE(attrib_map.empty());
  EXPECT_TRUE(uniform_map.empty());
  EXPECT_TRUE(varying_map.empty());
  EXPECT_TRUE(name_map.empty());
}

TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
  const char* shader = "foo-bar";

  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  // An invalid shader should fail.
  EXPECT_FALSE(fragment_translator_->Translate(shader,
                                               &info_log,
                                               &translated_source,
                                               &attrib_map,
                                               &uniform_map,
                                               &varying_map,
                                               &name_map));
  // Info log must be valid and non-empty.
  EXPECT_FALSE(info_log.empty());
  // Translated shader must be NULL.
  EXPECT_TRUE(translated_source.empty());
  // There should be no attributes or uniforms.
  EXPECT_TRUE(attrib_map.empty());
  EXPECT_TRUE(uniform_map.empty());
  EXPECT_TRUE(varying_map.empty());
  EXPECT_TRUE(name_map.empty());
}

TEST_F(ShaderTranslatorTest, GetAttributes) {
  const char* shader =
      "attribute vec4 vPosition;\n"
      "void main() {\n"
      "  gl_Position = vPosition;\n"
      "}";

  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_TRUE(vertex_translator_->Translate(shader,
                                            &info_log,
                                            &translated_source,
                                            &attrib_map,
                                            &uniform_map,
                                            &varying_map,
                                            &name_map));
  // Info log must be NULL.
  EXPECT_TRUE(info_log.empty());
  // Translated shader must be valid and non-empty.
  EXPECT_FALSE(translated_source.empty());
  // There should be no uniforms.
  EXPECT_TRUE(uniform_map.empty());
  // There should be one attribute with following characteristics:
  // name:vPosition type:GL_FLOAT_VEC4 size:1.
  EXPECT_EQ(1u, attrib_map.size());
  ShaderTranslator::VariableMap::const_iterator iter =
      attrib_map.find("vPosition");
  EXPECT_TRUE(iter != attrib_map.end());
  EXPECT_EQ(GL_FLOAT_VEC4, iter->second.type);
  EXPECT_EQ(1, iter->second.size);
  EXPECT_EQ("vPosition", iter->second.name);
}

TEST_F(ShaderTranslatorTest, GetUniforms) {
  const char* shader =
      "precision mediump float;\n"
      "struct Foo {\n"
      "  vec4 color[1];\n"
      "};\n"
      "struct Bar {\n"
      "  Foo foo;\n"
      "};\n"
      "uniform Bar bar[2];\n"
      "void main() {\n"
      "  gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
      "}";

  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_TRUE(fragment_translator_->Translate(shader,
                                              &info_log,
                                              &translated_source,
                                              &attrib_map,
                                              &uniform_map,
                                              &varying_map,
                                              &name_map));
  // Info log must be NULL.
  EXPECT_TRUE(info_log.empty());
  // Translated shader must be valid and non-empty.
  EXPECT_FALSE(translated_source.empty());
  // There should be no attributes.
  EXPECT_TRUE(attrib_map.empty());
  // There should be two uniforms with following characteristics:
  // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
  // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
  EXPECT_EQ(2u, uniform_map.size());
  // First uniform.
  ShaderTranslator::VariableMap::const_iterator iter =
      uniform_map.find("bar[0].foo.color[0]");
  EXPECT_TRUE(iter != uniform_map.end());
  EXPECT_EQ(GL_FLOAT_VEC4, iter->second.type);
  EXPECT_EQ(1, iter->second.size);
  EXPECT_EQ("bar[0].foo.color[0]", iter->second.name);
  // Second uniform.
  iter = uniform_map.find("bar[1].foo.color[0]");
  EXPECT_TRUE(iter != uniform_map.end());
  EXPECT_EQ(GL_FLOAT_VEC4, iter->second.type);
  EXPECT_EQ(1, iter->second.size);
  EXPECT_EQ("bar[1].foo.color[0]", iter->second.name);
}

#if defined(OS_MACOSX)
TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) {
  // This test might become invalid in the future when ANGLE Translator is no
  // longer emulate dot(float, float) in Mac, or the emulated function name is
  // no longer webgl_dot_emu.
  const char* shader =
      "void main() {\n"
      "  gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
      "}";

  std::string info_log, translated_source;
  ShaderTranslatorInterface::VariableMap attrib_map, uniform_map, varying_map;
  ShaderTranslatorInterface::NameMap name_map;
  EXPECT_TRUE(vertex_translator_->Translate(shader,
                                            &info_log,
                                            &translated_source,
                                            &attrib_map,
                                            &uniform_map,
                                            &varying_map,
                                            &name_map));
  // Info log must be NULL.
  EXPECT_TRUE(info_log.empty());
  // Translated shader must be valid and non-empty.
  ASSERT_FALSE(translated_source.empty());
  EXPECT_TRUE(strstr(translated_source.c_str(),
                     "webgl_dot_emu") != NULL);
}
#endif

TEST_F(ShaderTranslatorTest, OptionsString) {
  scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator();
  scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator();
  scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator();

  ShBuiltInResources resources;
  ShInitBuiltInResources(&resources);

  ASSERT_TRUE(translator_1->Init(
      GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
      ShaderTranslatorInterface::kGlsl,
      SH_EMULATE_BUILT_IN_FUNCTIONS));
  ASSERT_TRUE(translator_2->Init(
      GL_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
      ShaderTranslatorInterface::kGlsl,
      static_cast<ShCompileOptions>(0)));
  resources.EXT_draw_buffers = 1;
  ASSERT_TRUE(translator_3->Init(
      GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
      ShaderTranslatorInterface::kGlsl,
      SH_EMULATE_BUILT_IN_FUNCTIONS));

  std::string options_1(
      translator_1->GetStringForOptionsThatWouldAffectCompilation());
  std::string options_2(
      translator_1->GetStringForOptionsThatWouldAffectCompilation());
  std::string options_3(
      translator_2->GetStringForOptionsThatWouldAffectCompilation());
  std::string options_4(
      translator_3->GetStringForOptionsThatWouldAffectCompilation());

  EXPECT_EQ(options_1, options_2);
  EXPECT_NE(options_1, options_3);
  EXPECT_NE(options_1, options_4);
  EXPECT_NE(options_3, options_4);
}

}  // namespace gles2
}  // namespace gpu

