// Copyright (c) 2019 Google LLC
//
// 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 "source/fuzz/fuzzer_pass_add_useful_constructs.h"
#include "source/fuzz/pseudo_random_generator.h"
#include "source/fuzz/uniform_buffer_element_descriptor.h"
#include "test/fuzz/fuzz_test_util.h"

namespace spvtools {
namespace fuzz {
namespace {

bool AddFactHelper(
    FactManager* fact_manager, opt::IRContext* context, uint32_t word,
    const protobufs::UniformBufferElementDescriptor& descriptor) {
  protobufs::FactConstantUniform constant_uniform_fact;
  constant_uniform_fact.add_constant_word(word);
  *constant_uniform_fact.mutable_uniform_buffer_element_descriptor() =
      descriptor;
  protobufs::Fact fact;
  *fact.mutable_constant_uniform_fact() = constant_uniform_fact;
  return fact_manager->AddFact(fact, context);
}

TEST(FuzzerPassAddUsefulConstructsTest, CheckBasicStuffIsAdded) {
  // The SPIR-V came from the following empty GLSL shader:
  //
  // #version 450
  //
  // void main()
  // {
  // }

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource GLSL 450
               OpName %4 "main"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
  protobufs::TransformationSequence transformation_sequence;

  FuzzerPassAddUsefulConstructs pass(context.get(), &transformation_context,
                                     &fuzzer_context, &transformation_sequence);
  pass.Apply();
  ASSERT_TRUE(IsValid(env, context.get()));

  std::string after = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource GLSL 450
               OpName %4 "main"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
        %100 = OpTypeBool
        %101 = OpTypeInt 32 1
        %102 = OpTypeInt 32 0
        %103 = OpTypeFloat 32
        %104 = OpConstantTrue %100
        %105 = OpConstantFalse %100
        %106 = OpConstant %101 0
        %107 = OpConstant %101 1
        %108 = OpConstant %102 0
        %109 = OpConstant %102 1
        %110 = OpConstant %103 0
        %111 = OpConstant %103 1
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";
  ASSERT_TRUE(IsEqual(env, after, context.get()));
}

TEST(FuzzerPassAddUsefulConstructsTest,
     CheckTypesIndicesAndConstantsAddedForUniformFacts) {
  // The SPIR-V came from the following GLSL shader:
  //
  // #version 450
  //
  // struct S {
  //   int x;
  //   float y;
  //   int z;
  //   int w;
  // };
  //
  // uniform buf {
  //   S s;
  //   uint w[10];
  // };
  //
  // void main() {
  // }

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource GLSL 450
               OpName %4 "main"
               OpName %8 "S"
               OpMemberName %8 0 "x"
               OpMemberName %8 1 "y"
               OpMemberName %8 2 "z"
               OpMemberName %8 3 "w"
               OpName %12 "buf"
               OpMemberName %12 0 "s"
               OpMemberName %12 1 "w"
               OpName %14 ""
               OpMemberDecorate %8 0 Offset 0
               OpMemberDecorate %8 1 Offset 4
               OpMemberDecorate %8 2 Offset 8
               OpMemberDecorate %8 3 Offset 12
               OpDecorate %11 ArrayStride 16
               OpMemberDecorate %12 0 Offset 0
               OpMemberDecorate %12 1 Offset 16
               OpDecorate %12 Block
               OpDecorate %14 DescriptorSet 0
               OpDecorate %14 Binding 0
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypeFloat 32
          %8 = OpTypeStruct %6 %7 %6 %6
          %9 = OpTypeInt 32 0
         %10 = OpConstant %9 10
         %11 = OpTypeArray %9 %10
         %12 = OpTypeStruct %8 %11
         %13 = OpTypePointer Uniform %12
         %14 = OpVariable %13 Uniform
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
  protobufs::TransformationSequence transformation_sequence;

  // Add some uniform facts.

  // buf.s.x == 200
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 200,
                            MakeUniformBufferElementDescriptor(0, 0, {0, 0})));

  // buf.s.y == 0.5
  const float float_value = 0.5;
  uint32_t float_value_as_uint;
  memcpy(&float_value_as_uint, &float_value, sizeof(float_value));
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_value_as_uint,
                            MakeUniformBufferElementDescriptor(0, 0, {0, 1})));

  // buf.s.z == 300
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 300,
                            MakeUniformBufferElementDescriptor(0, 0, {0, 2})));

  // buf.s.w == 400
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 400,
                            MakeUniformBufferElementDescriptor(0, 0, {0, 3})));

  // buf.w[6] = 22
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 22,
                            MakeUniformBufferElementDescriptor(0, 0, {1, 6})));

  // buf.w[8] = 23
  ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 23,
                            MakeUniformBufferElementDescriptor(0, 0, {1, 8})));

  // Assert some things about the module that are not true prior to adding the
  // pass

  {
    // No uniform int pointer
    opt::analysis::Integer temp_type_signed_int(32, true);
    opt::analysis::Integer* registered_type_signed_int =
        context->get_type_mgr()
            ->GetRegisteredType(&temp_type_signed_int)
            ->AsInteger();
    opt::analysis::Pointer type_pointer_uniform_signed_int(
        registered_type_signed_int, SpvStorageClassUniform);
    ASSERT_EQ(0,
              context->get_type_mgr()->GetId(&type_pointer_uniform_signed_int));

    // No uniform uint pointer
    opt::analysis::Integer temp_type_unsigned_int(32, false);
    opt::analysis::Integer* registered_type_unsigned_int =
        context->get_type_mgr()
            ->GetRegisteredType(&temp_type_unsigned_int)
            ->AsInteger();
    opt::analysis::Pointer type_pointer_uniform_unsigned_int(
        registered_type_unsigned_int, SpvStorageClassUniform);
    ASSERT_EQ(
        0, context->get_type_mgr()->GetId(&type_pointer_uniform_unsigned_int));

    // No uniform float pointer
    opt::analysis::Float temp_type_float(32);
    opt::analysis::Float* registered_type_float =
        context->get_type_mgr()->GetRegisteredType(&temp_type_float)->AsFloat();
    opt::analysis::Pointer type_pointer_uniform_float(registered_type_float,
                                                      SpvStorageClassUniform);
    ASSERT_EQ(0, context->get_type_mgr()->GetId(&type_pointer_uniform_float));

    // No int constants 200, 300 nor 400
    opt::analysis::IntConstant int_constant_200(registered_type_signed_int,
                                                {200});
    opt::analysis::IntConstant int_constant_300(registered_type_signed_int,
                                                {300});
    opt::analysis::IntConstant int_constant_400(registered_type_signed_int,
                                                {400});
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_200));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_300));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_400));

    // No float constant 0.5
    opt::analysis::FloatConstant float_constant_zero_point_five(
        registered_type_float, {float_value_as_uint});
    ASSERT_EQ(nullptr, context->get_constant_mgr()->FindConstant(
                           &float_constant_zero_point_five));

    // No uint constant 22
    opt::analysis::IntConstant uint_constant_22(registered_type_unsigned_int,
                                                {22});
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&uint_constant_22));

    // No uint constant 23
    opt::analysis::IntConstant uint_constant_23(registered_type_unsigned_int,
                                                {23});
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&uint_constant_23));

    // No int constants 0, 1, 2, 3, 6, 8
    opt::analysis::IntConstant int_constant_0(registered_type_signed_int, {0});
    opt::analysis::IntConstant int_constant_1(registered_type_signed_int, {1});
    opt::analysis::IntConstant int_constant_2(registered_type_signed_int, {2});
    opt::analysis::IntConstant int_constant_3(registered_type_signed_int, {3});
    opt::analysis::IntConstant int_constant_6(registered_type_signed_int, {6});
    opt::analysis::IntConstant int_constant_8(registered_type_signed_int, {8});
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_0));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_1));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_2));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_3));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_6));
    ASSERT_EQ(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_8));
  }

  FuzzerPassAddUsefulConstructs pass(context.get(), &transformation_context,
                                     &fuzzer_context, &transformation_sequence);
  pass.Apply();
  ASSERT_TRUE(IsValid(env, context.get()));

  // Now assert some things about the module that should be true following the
  // pass.

  // We reconstruct all necessary types and constants to guard against the type
  // and constant managers for the module having been invalidated.

  {
    // Uniform int pointer now present
    opt::analysis::Integer temp_type_signed_int(32, true);
    opt::analysis::Integer* registered_type_signed_int =
        context->get_type_mgr()
            ->GetRegisteredType(&temp_type_signed_int)
            ->AsInteger();
    opt::analysis::Pointer type_pointer_uniform_signed_int(
        registered_type_signed_int, SpvStorageClassUniform);
    ASSERT_NE(0,
              context->get_type_mgr()->GetId(&type_pointer_uniform_signed_int));

    // Uniform uint pointer now present
    opt::analysis::Integer temp_type_unsigned_int(32, false);
    opt::analysis::Integer* registered_type_unsigned_int =
        context->get_type_mgr()
            ->GetRegisteredType(&temp_type_unsigned_int)
            ->AsInteger();
    opt::analysis::Pointer type_pointer_uniform_unsigned_int(
        registered_type_unsigned_int, SpvStorageClassUniform);
    ASSERT_NE(
        0, context->get_type_mgr()->GetId(&type_pointer_uniform_unsigned_int));

    // Uniform float pointer now present
    opt::analysis::Float temp_type_float(32);
    opt::analysis::Float* registered_type_float =
        context->get_type_mgr()->GetRegisteredType(&temp_type_float)->AsFloat();
    opt::analysis::Pointer type_pointer_uniform_float(registered_type_float,
                                                      SpvStorageClassUniform);
    ASSERT_NE(0, context->get_type_mgr()->GetId(&type_pointer_uniform_float));

    // int constants 200, 300, 400 now present
    opt::analysis::IntConstant int_constant_200(registered_type_signed_int,
                                                {200});
    opt::analysis::IntConstant int_constant_300(registered_type_signed_int,
                                                {300});
    opt::analysis::IntConstant int_constant_400(registered_type_signed_int,
                                                {400});
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_200));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_300));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_400));

    // float constant 0.5 now present
    opt::analysis::FloatConstant float_constant_zero_point_five(
        registered_type_float, {float_value_as_uint});
    ASSERT_NE(nullptr, context->get_constant_mgr()->FindConstant(
                           &float_constant_zero_point_five));

    // uint constant 22 now present
    opt::analysis::IntConstant uint_constant_22(registered_type_unsigned_int,
                                                {22});
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&uint_constant_22));

    // uint constant 23 now present
    opt::analysis::IntConstant uint_constant_23(registered_type_unsigned_int,
                                                {23});
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&uint_constant_23));

    // int constants 0, 1, 2, 3, 6, 8 now present
    opt::analysis::IntConstant int_constant_0(registered_type_signed_int, {0});
    opt::analysis::IntConstant int_constant_1(registered_type_signed_int, {1});
    opt::analysis::IntConstant int_constant_2(registered_type_signed_int, {2});
    opt::analysis::IntConstant int_constant_3(registered_type_signed_int, {3});
    opt::analysis::IntConstant int_constant_6(registered_type_signed_int, {6});
    opt::analysis::IntConstant int_constant_8(registered_type_signed_int, {8});
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_0));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_1));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_2));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_3));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_6));
    ASSERT_NE(nullptr,
              context->get_constant_mgr()->FindConstant(&int_constant_8));
  }
}

}  // namespace
}  // namespace fuzz
}  // namespace spvtools
