// Copyright (c) 2015-2016 The Khronos Group 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 <algorithm>
#include <string>
#include <vector>

#include "source/latest_version_glsl_std_450_header.h"
#include "test/unit_spirv.h"

namespace spvtools {
namespace {

/// Context for an extended instruction.
///
/// Information about a GLSL extended instruction (including its opname, return
/// type, etc.) and related instructions used to generate the return type and
/// constant as the operands. Used in generating extended instruction tests.
struct ExtInstContext {
  const char* extInstOpName;
  const char* extInstOperandVars;
  /// The following fields are used to check the SPIR-V binary representation
  /// of this instruction.
  uint32_t extInstOpcode;  ///< Opcode value for this extended instruction.
  uint32_t extInstLength;  ///< Wordcount of this extended instruction.
  std::vector<uint32_t> extInstOperandIds;  ///< Ids for operands.
};

using ExtInstGLSLstd450RoundTripTest = ::testing::TestWithParam<ExtInstContext>;

TEST_P(ExtInstGLSLstd450RoundTripTest, ParameterizedExtInst) {
  spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_0);
  const std::string spirv = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical Simple
OpEntryPoint Vertex %2 "main"
%3 = OpTypeVoid
%4 = OpTypeFunction %3
%2 = OpFunction %3 None %5
%6 = OpLabel
%8 = OpExtInst %7 %1 )" + std::string(GetParam().extInstOpName) +
                            " " + GetParam().extInstOperandVars + R"(
OpReturn
OpFunctionEnd
)";
  const std::string spirv_header =
      R"(; SPIR-V
; Version: 1.0
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 9
; Schema: 0)";
  spv_binary binary = nullptr;
  spv_diagnostic diagnostic;
  spv_result_t error = spvTextToBinary(context, spirv.c_str(), spirv.size(),
                                       &binary, &diagnostic);
  if (error) {
    spvDiagnosticPrint(diagnostic);
    spvDiagnosticDestroy(diagnostic);
    ASSERT_EQ(SPV_SUCCESS, error)
        << "Source was: " << std::endl
        << spirv << std::endl
        << "Test case for : " << GetParam().extInstOpName << std::endl;
  }

  // Check we do have the extended instruction's corresponding binary code in
  // the generated SPIR-V binary.
  std::vector<uint32_t> expected_contains(
      {12 /*OpExtInst*/ | GetParam().extInstLength << 16, 7 /*return type*/,
       8 /*result id*/, 1 /*glsl450 import*/, GetParam().extInstOpcode});
  for (uint32_t operand : GetParam().extInstOperandIds) {
    expected_contains.push_back(operand);
  }
  EXPECT_NE(binary->code + binary->wordCount,
            std::search(binary->code, binary->code + binary->wordCount,
                        expected_contains.begin(), expected_contains.end()))
      << "Cannot find\n"
      << spvtest::WordVector(expected_contains).str() << "in\n"
      << spvtest::WordVector(*binary).str();

  // Check round trip gives the same text.
  spv_text output_text = nullptr;
  error = spvBinaryToText(context, binary->code, binary->wordCount,
                          SPV_BINARY_TO_TEXT_OPTION_NONE, &output_text,
                          &diagnostic);

  if (error) {
    spvDiagnosticPrint(diagnostic);
    spvDiagnosticDestroy(diagnostic);
    ASSERT_EQ(SPV_SUCCESS, error);
  }
  EXPECT_EQ(spirv_header + spirv, output_text->str);
  spvTextDestroy(output_text);
  spvBinaryDestroy(binary);
  spvContextDestroy(context);
}

INSTANTIATE_TEST_CASE_P(
    ExtInstParameters, ExtInstGLSLstd450RoundTripTest,
    ::testing::ValuesIn(std::vector<ExtInstContext>({
        // We are only testing the correctness of encoding and decoding here.
        // Semantic correctness should be the responsibility of validator. So
        // some of the instructions below have incorrect operand and/or return
        // types, e.g, Modf, ModfStruct, etc.
        {"Round", "%5", 1, 6, {5}},
        {"RoundEven", "%5", 2, 6, {5}},
        {"Trunc", "%5", 3, 6, {5}},
        {"FAbs", "%5", 4, 6, {5}},
        {"SAbs", "%5", 5, 6, {5}},
        {"FSign", "%5", 6, 6, {5}},
        {"SSign", "%5", 7, 6, {5}},
        {"Floor", "%5", 8, 6, {5}},
        {"Ceil", "%5", 9, 6, {5}},
        {"Fract", "%5", 10, 6, {5}},
        {"Radians", "%5", 11, 6, {5}},
        {"Degrees", "%5", 12, 6, {5}},
        {"Sin", "%5", 13, 6, {5}},
        {"Cos", "%5", 14, 6, {5}},
        {"Tan", "%5", 15, 6, {5}},
        {"Asin", "%5", 16, 6, {5}},
        {"Acos", "%5", 17, 6, {5}},
        {"Atan", "%5", 18, 6, {5}},
        {"Sinh", "%5", 19, 6, {5}},
        {"Cosh", "%5", 20, 6, {5}},
        {"Tanh", "%5", 21, 6, {5}},
        {"Asinh", "%5", 22, 6, {5}},
        {"Acosh", "%5", 23, 6, {5}},
        {"Atanh", "%5", 24, 6, {5}},
        {"Atan2", "%5 %5", 25, 7, {5, 5}},
        {"Pow", "%5 %5", 26, 7, {5, 5}},
        {"Exp", "%5", 27, 6, {5}},
        {"Log", "%5", 28, 6, {5}},
        {"Exp2", "%5", 29, 6, {5}},
        {"Log2", "%5", 30, 6, {5}},
        {"Sqrt", "%5", 31, 6, {5}},
        {"InverseSqrt", "%5", 32, 6, {5}},
        {"Determinant", "%5", 33, 6, {5}},
        {"MatrixInverse", "%5", 34, 6, {5}},
        {"Modf", "%5 %5", 35, 7, {5, 5}},
        {"ModfStruct", "%5", 36, 6, {5}},
        {"FMin", "%5 %5", 37, 7, {5, 5}},
        {"UMin", "%5 %5", 38, 7, {5, 5}},
        {"SMin", "%5 %5", 39, 7, {5, 5}},
        {"FMax", "%5 %5", 40, 7, {5, 5}},
        {"UMax", "%5 %5", 41, 7, {5, 5}},
        {"SMax", "%5 %5", 42, 7, {5, 5}},
        {"FClamp", "%5 %5 %5", 43, 8, {5, 5, 5}},
        {"UClamp", "%5 %5 %5", 44, 8, {5, 5, 5}},
        {"SClamp", "%5 %5 %5", 45, 8, {5, 5, 5}},
        {"FMix", "%5 %5 %5", 46, 8, {5, 5, 5}},
        {"IMix", "%5 %5 %5", 47, 8, {5, 5, 5}},  // Bug 15452. Reserved.
        {"Step", "%5 %5", 48, 7, {5, 5}},
        {"SmoothStep", "%5 %5 %5", 49, 8, {5, 5, 5}},
        {"Fma", "%5 %5 %5", 50, 8, {5, 5, 5}},
        {"Frexp", "%5 %5", 51, 7, {5, 5}},
        {"FrexpStruct", "%5", 52, 6, {5}},
        {"Ldexp", "%5 %5", 53, 7, {5, 5}},
        {"PackSnorm4x8", "%5", 54, 6, {5}},
        {"PackUnorm4x8", "%5", 55, 6, {5}},
        {"PackSnorm2x16", "%5", 56, 6, {5}},
        {"PackUnorm2x16", "%5", 57, 6, {5}},
        {"PackHalf2x16", "%5", 58, 6, {5}},
        {"PackDouble2x32", "%5", 59, 6, {5}},
        {"UnpackSnorm2x16", "%5", 60, 6, {5}},
        {"UnpackUnorm2x16", "%5", 61, 6, {5}},
        {"UnpackHalf2x16", "%5", 62, 6, {5}},
        {"UnpackSnorm4x8", "%5", 63, 6, {5}},
        {"UnpackUnorm4x8", "%5", 64, 6, {5}},
        {"UnpackDouble2x32", "%5", 65, 6, {5}},
        {"Length", "%5", 66, 6, {5}},
        {"Distance", "%5 %5", 67, 7, {5, 5}},
        {"Cross", "%5 %5", 68, 7, {5, 5}},
        {"Normalize", "%5", 69, 6, {5}},
        // clang-format off
        {"FaceForward", "%5 %5 %5", 70, 8, {5, 5, 5}},
        // clang-format on
        {"Reflect", "%5 %5", 71, 7, {5, 5}},
        {"Refract", "%5 %5 %5", 72, 8, {5, 5, 5}},
        {"FindILsb", "%5", 73, 6, {5}},
        {"FindSMsb", "%5", 74, 6, {5}},
        {"FindUMsb", "%5", 75, 6, {5}},
        {"InterpolateAtCentroid", "%5", 76, 6, {5}},
        // clang-format off
        {"InterpolateAtSample", "%5 %5", 77, 7, {5, 5}},
        {"InterpolateAtOffset", "%5 %5", 78, 7, {5, 5}},
        // clang-format on
        {"NMin", "%5 %5", 79, 7, {5, 5}},
        {"NMax", "%5 %5", 80, 7, {5, 5}},
        {"NClamp", "%5 %5 %5", 81, 8, {5, 5, 5}},
    })), );

}  // namespace
}  // namespace spvtools
