// Copyright (c) 2016 Google Inc.
//
// 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 <string>
#include <utility>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "spirv-tools/optimizer.hpp"
#include "spirv/1.1/spirv.h"

namespace spvtools {
namespace {

using ::testing::ContainerEq;
using ::testing::HasSubstr;

// Return a string that contains the minimum instructions needed to form
// a valid module.  Other instructions can be appended to this string.
std::string Header() {
  return R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
)";
}

// When we assemble with a target environment of SPIR-V 1.1, we expect
// the following in the module header version word.
const uint32_t kExpectedSpvVersion = 0x10100;

TEST(CppInterface, SuccessfulRoundTrip) {
  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);

  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(input_text, &binary));
  EXPECT_TRUE(binary.size() > 5u);
  EXPECT_EQ(SpvMagicNumber, binary[0]);
  EXPECT_EQ(kExpectedSpvVersion, binary[1]);

  // This cannot pass validation since %1 is not defined.
  t.SetMessageConsumer([](spv_message_level_t level, const char* source,
                          const spv_position_t& position, const char* message) {
    EXPECT_EQ(SPV_MSG_ERROR, level);
    EXPECT_STREQ("input", source);
    EXPECT_EQ(0u, position.line);
    EXPECT_EQ(0u, position.column);
    EXPECT_EQ(1u, position.index);
    EXPECT_STREQ("ID '1[%1]' has not been defined\n  %2 = OpSizeOf %1 %3\n",
                 message);
  });
  EXPECT_FALSE(t.Validate(binary));

  std::string output_text;
  EXPECT_TRUE(t.Disassemble(binary, &output_text));
  EXPECT_EQ(input_text, output_text);
}

TEST(CppInterface, AssembleEmptyModule) {
  std::vector<uint32_t> binary(10, 42);
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  EXPECT_TRUE(t.Assemble("", &binary));
  // We only have the header.
  EXPECT_EQ(5u, binary.size());
  EXPECT_EQ(SpvMagicNumber, binary[0]);
  EXPECT_EQ(kExpectedSpvVersion, binary[1]);
}

TEST(CppInterface, AssembleOverloads) {
  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  {
    std::vector<uint32_t> binary;
    EXPECT_TRUE(t.Assemble(input_text, &binary));
    EXPECT_TRUE(binary.size() > 5u);
    EXPECT_EQ(SpvMagicNumber, binary[0]);
    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
  }
  {
    std::vector<uint32_t> binary;
    EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size(), &binary));
    EXPECT_TRUE(binary.size() > 5u);
    EXPECT_EQ(SpvMagicNumber, binary[0]);
    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
  }
  {  // Ignore the last newline.
    std::vector<uint32_t> binary;
    EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size() - 1, &binary));
    EXPECT_TRUE(binary.size() > 5u);
    EXPECT_EQ(SpvMagicNumber, binary[0]);
    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
  }
}

TEST(CppInterface, DisassembleEmptyModule) {
  std::string text(10, 'x');
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  int invocation_count = 0;
  t.SetMessageConsumer(
      [&invocation_count](spv_message_level_t level, const char* source,
                          const spv_position_t& position, const char* message) {
        ++invocation_count;
        EXPECT_EQ(SPV_MSG_ERROR, level);
        EXPECT_STREQ("input", source);
        EXPECT_EQ(0u, position.line);
        EXPECT_EQ(0u, position.column);
        EXPECT_EQ(0u, position.index);
        EXPECT_STREQ("Missing module.", message);
      });
  EXPECT_FALSE(t.Disassemble({}, &text));
  EXPECT_EQ("xxxxxxxxxx", text);  // The original string is unmodified.
  EXPECT_EQ(1, invocation_count);
}

TEST(CppInterface, DisassembleOverloads) {
  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);

  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(input_text, &binary));

  {
    std::string output_text;
    EXPECT_TRUE(t.Disassemble(binary, &output_text));
    EXPECT_EQ(input_text, output_text);
  }
  {
    std::string output_text;
    EXPECT_TRUE(t.Disassemble(binary.data(), binary.size(), &output_text));
    EXPECT_EQ(input_text, output_text);
  }
}

TEST(CppInterface, SuccessfulValidation) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  int invocation_count = 0;
  t.SetMessageConsumer([&invocation_count](spv_message_level_t, const char*,
                                           const spv_position_t&, const char*) {
    ++invocation_count;
  });

  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(Header(), &binary));
  EXPECT_TRUE(t.Validate(binary));
  EXPECT_EQ(0, invocation_count);
}

TEST(CppInterface, ValidateOverloads) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(Header(), &binary));

  { EXPECT_TRUE(t.Validate(binary)); }
  { EXPECT_TRUE(t.Validate(binary.data(), binary.size())); }
}

TEST(CppInterface, ValidateEmptyModule) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  int invocation_count = 0;
  t.SetMessageConsumer(
      [&invocation_count](spv_message_level_t level, const char* source,
                          const spv_position_t& position, const char* message) {
        ++invocation_count;
        EXPECT_EQ(SPV_MSG_ERROR, level);
        EXPECT_STREQ("input", source);
        EXPECT_EQ(0u, position.line);
        EXPECT_EQ(0u, position.column);
        EXPECT_EQ(0u, position.index);
        EXPECT_STREQ("Invalid SPIR-V magic number.", message);
      });
  EXPECT_FALSE(t.Validate({}));
  EXPECT_EQ(1, invocation_count);
}

// Returns the assembly for a SPIR-V module with a struct declaration
// with the given number of members.
std::string MakeModuleHavingStruct(int num_members) {
  std::stringstream os;
  os << Header();
  os << R"(%1 = OpTypeInt 32 0
           %2 = OpTypeStruct)";
  for (int i = 0; i < num_members; i++) os << " %1";
  return os.str();
}

TEST(CppInterface, ValidateWithOptionsPass) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
  const ValidatorOptions opts;

  EXPECT_TRUE(t.Validate(binary.data(), binary.size(), opts));
}

TEST(CppInterface, ValidateWithOptionsFail) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
  ValidatorOptions opts;
  opts.SetUniversalLimit(spv_validator_limit_max_struct_members, 9);
  std::stringstream os;
  t.SetMessageConsumer([&os](spv_message_level_t, const char*,
                             const spv_position_t&,
                             const char* message) { os << message; });

  EXPECT_FALSE(t.Validate(binary.data(), binary.size(), opts));
  EXPECT_THAT(
      os.str(),
      HasSubstr(
          "Number of OpTypeStruct members (10) has exceeded the limit (9)"));
}

// Checks that after running the given optimizer |opt| on the given |original|
// source code, we can get the given |optimized| source code.
void CheckOptimization(const std::string& original,
                       const std::string& optimized, const Optimizer& opt) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> original_binary;
  ASSERT_TRUE(t.Assemble(original, &original_binary));

  std::vector<uint32_t> optimized_binary;
  EXPECT_TRUE(opt.Run(original_binary.data(), original_binary.size(),
                      &optimized_binary));

  std::string optimized_text;
  EXPECT_TRUE(t.Disassemble(optimized_binary, &optimized_text));
  EXPECT_EQ(optimized, optimized_text);
}

TEST(CppInterface, OptimizeEmptyModule) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary;
  EXPECT_TRUE(t.Assemble("", &binary));

  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
  o.RegisterPass(CreateStripDebugInfoPass());

  // Fails to validate.
  EXPECT_FALSE(o.Run(binary.data(), binary.size(), &binary));
}

TEST(CppInterface, OptimizeModifiedModule) {
  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
  o.RegisterPass(CreateStripDebugInfoPass());
  CheckOptimization(Header() + "OpSource GLSL 450", Header(), o);
}

TEST(CppInterface, OptimizeMulitplePasses) {
  std::string original_text = Header() +
                              "OpSource GLSL 450 "
                              "OpDecorate %true SpecId 1 "
                              "%bool = OpTypeBool "
                              "%true = OpSpecConstantTrue %bool";

  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
  o.RegisterPass(CreateStripDebugInfoPass())
      .RegisterPass(CreateFreezeSpecConstantValuePass());

  std::string expected_text = Header() +
                              "%bool = OpTypeBool\n"
                              "%true = OpConstantTrue %bool\n";

  CheckOptimization(original_text, expected_text, o);
}

TEST(CppInterface, OptimizeDoNothingWithPassToken) {
  CreateFreezeSpecConstantValuePass();
  auto token = CreateUnifyConstantPass();
}

TEST(CppInterface, OptimizeReassignPassToken) {
  auto token = CreateNullPass();
  token = CreateStripDebugInfoPass();

  CheckOptimization(
      Header() + "OpSource GLSL 450", Header(),
      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token)));
}

TEST(CppInterface, OptimizeMoveConstructPassToken) {
  auto token1 = CreateStripDebugInfoPass();
  Optimizer::PassToken token2(std::move(token1));

  CheckOptimization(
      Header() + "OpSource GLSL 450", Header(),
      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token2)));
}

TEST(CppInterface, OptimizeMoveAssignPassToken) {
  auto token1 = CreateStripDebugInfoPass();
  auto token2 = CreateNullPass();
  token2 = std::move(token1);

  CheckOptimization(
      Header() + "OpSource GLSL 450", Header(),
      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token2)));
}

TEST(CppInterface, OptimizeSameAddressForOriginalOptimizedBinary) {
  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
  std::vector<uint32_t> binary;
  ASSERT_TRUE(t.Assemble(Header() + "OpSource GLSL 450", &binary));

  EXPECT_TRUE(Optimizer(SPV_ENV_UNIVERSAL_1_1)
                  .RegisterPass(CreateStripDebugInfoPass())
                  .Run(binary.data(), binary.size(), &binary));

  std::string optimized_text;
  EXPECT_TRUE(t.Disassemble(binary, &optimized_text));
  EXPECT_EQ(Header(), optimized_text);
}

// TODO(antiagainst): tests for SetMessageConsumer().

}  // namespace
}  // namespace spvtools
