// Copyright (c) 2020 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/replayer.h"

#include "gtest/gtest.h"
#include "source/fuzz/data_descriptor.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_add_constant_scalar.h"
#include "source/fuzz/transformation_add_global_variable.h"
#include "source/fuzz/transformation_add_parameter.h"
#include "source/fuzz/transformation_add_synonym.h"
#include "source/fuzz/transformation_split_block.h"
#include "test/fuzz/fuzz_test_util.h"

namespace spvtools {
namespace fuzz {
namespace {

TEST(ReplayerTest, PartialReplay) {
  const std::string kTestShader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "g"
               OpName %11 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Private %6
          %8 = OpVariable %7 Private
          %9 = OpConstant %6 10
         %10 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %11 = OpVariable %10 Function
               OpStore %8 %9
         %12 = OpLoad %6 %8
               OpStore %11 %12
         %13 = OpLoad %6 %8
               OpStore %11 %13
         %14 = OpLoad %6 %8
               OpStore %11 %14
         %15 = OpLoad %6 %8
               OpStore %11 %15
         %16 = OpLoad %6 %8
               OpStore %11 %16
         %17 = OpLoad %6 %8
               OpStore %11 %17
         %18 = OpLoad %6 %8
               OpStore %11 %18
         %19 = OpLoad %6 %8
               OpStore %11 %19
         %20 = OpLoad %6 %8
               OpStore %11 %20
         %21 = OpLoad %6 %8
               OpStore %11 %21
         %22 = OpLoad %6 %8
               OpStore %11 %22
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  spvtools::ValidatorOptions validator_options;

  std::vector<uint32_t> binary_in;
  SpirvTools t(env);
  t.SetMessageConsumer(kConsoleMessageConsumer);
  ASSERT_TRUE(t.Assemble(kTestShader, &binary_in, kFuzzAssembleOption));
  ASSERT_TRUE(t.Validate(binary_in));

  protobufs::TransformationSequence transformations;
  for (uint32_t id = 12; id <= 22; id++) {
    *transformations.add_transformation() =
        TransformationSplitBlock(MakeInstructionDescriptor(id, SpvOpLoad, 0),
                                 id + 100)
            .ToMessage();
  }

  {
    // Full replay
    protobufs::FactSequence empty_facts;
    auto replayer_result =
        Replayer(env, kConsoleMessageConsumer, binary_in, empty_facts,
                 transformations, 11, true, validator_options)
            .Run();
    // Replay should succeed.
    ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete,
              replayer_result.status);
    // All transformations should be applied.
    ASSERT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
        transformations, replayer_result.applied_transformations));

    const std::string kFullySplitShader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "g"
               OpName %11 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Private %6
          %8 = OpVariable %7 Private
          %9 = OpConstant %6 10
         %10 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %11 = OpVariable %10 Function
               OpStore %8 %9
               OpBranch %112
        %112 = OpLabel
         %12 = OpLoad %6 %8
               OpStore %11 %12
               OpBranch %113
        %113 = OpLabel
         %13 = OpLoad %6 %8
               OpStore %11 %13
               OpBranch %114
        %114 = OpLabel
         %14 = OpLoad %6 %8
               OpStore %11 %14
               OpBranch %115
        %115 = OpLabel
         %15 = OpLoad %6 %8
               OpStore %11 %15
               OpBranch %116
        %116 = OpLabel
         %16 = OpLoad %6 %8
               OpStore %11 %16
               OpBranch %117
        %117 = OpLabel
         %17 = OpLoad %6 %8
               OpStore %11 %17
               OpBranch %118
        %118 = OpLabel
         %18 = OpLoad %6 %8
               OpStore %11 %18
               OpBranch %119
        %119 = OpLabel
         %19 = OpLoad %6 %8
               OpStore %11 %19
               OpBranch %120
        %120 = OpLabel
         %20 = OpLoad %6 %8
               OpStore %11 %20
               OpBranch %121
        %121 = OpLabel
         %21 = OpLoad %6 %8
               OpStore %11 %21
               OpBranch %122
        %122 = OpLabel
         %22 = OpLoad %6 %8
               OpStore %11 %22
               OpReturn
               OpFunctionEnd
    )";
    ASSERT_TRUE(IsEqual(env, kFullySplitShader,
                        replayer_result.transformed_module.get()));
  }

  {
    // Half replay
    protobufs::FactSequence empty_facts;
    auto replayer_result =
        Replayer(env, kConsoleMessageConsumer, binary_in, empty_facts,
                 transformations, 5, true, validator_options)
            .Run();
    // Replay should succeed.
    ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete,
              replayer_result.status);
    // The first 5 transformations should be applied
    ASSERT_EQ(5, replayer_result.applied_transformations.transformation_size());
    for (uint32_t i = 0; i < 5; i++) {
      ASSERT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
          transformations.transformation(i),
          replayer_result.applied_transformations.transformation(i)));
    }

    const std::string kHalfSplitShader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "g"
               OpName %11 "x"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Private %6
          %8 = OpVariable %7 Private
          %9 = OpConstant %6 10
         %10 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %11 = OpVariable %10 Function
               OpStore %8 %9
               OpBranch %112
        %112 = OpLabel
         %12 = OpLoad %6 %8
               OpStore %11 %12
               OpBranch %113
        %113 = OpLabel
         %13 = OpLoad %6 %8
               OpStore %11 %13
               OpBranch %114
        %114 = OpLabel
         %14 = OpLoad %6 %8
               OpStore %11 %14
               OpBranch %115
        %115 = OpLabel
         %15 = OpLoad %6 %8
               OpStore %11 %15
               OpBranch %116
        %116 = OpLabel
         %16 = OpLoad %6 %8
               OpStore %11 %16
         %17 = OpLoad %6 %8
               OpStore %11 %17
         %18 = OpLoad %6 %8
               OpStore %11 %18
         %19 = OpLoad %6 %8
               OpStore %11 %19
         %20 = OpLoad %6 %8
               OpStore %11 %20
         %21 = OpLoad %6 %8
               OpStore %11 %21
         %22 = OpLoad %6 %8
               OpStore %11 %22
               OpReturn
               OpFunctionEnd
    )";
    ASSERT_TRUE(IsEqual(env, kHalfSplitShader,
                        replayer_result.transformed_module.get()));
  }

  {
    // Empty replay
    protobufs::FactSequence empty_facts;
    auto replayer_result =
        Replayer(env, kConsoleMessageConsumer, binary_in, empty_facts,
                 transformations, 0, true, validator_options)
            .Run();
    // Replay should succeed.
    ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete,
              replayer_result.status);
    // No transformations should be applied
    ASSERT_EQ(0, replayer_result.applied_transformations.transformation_size());
    ASSERT_TRUE(
        IsEqual(env, kTestShader, replayer_result.transformed_module.get()));
  }

  {
    // Invalid replay: too many transformations
    protobufs::FactSequence empty_facts;
    // The number of transformations requested to be applied exceeds the number
    // of transformations
    auto replayer_result =
        Replayer(env, kConsoleMessageConsumer, binary_in, empty_facts,
                 transformations, 12, true, validator_options)
            .Run();

    // Replay should not succeed.
    ASSERT_EQ(Replayer::ReplayerResultStatus::kTooManyTransformationsRequested,
              replayer_result.status);
    // No transformations should be applied
    ASSERT_EQ(0, replayer_result.applied_transformations.transformation_size());
    // The output binary should be empty
    ASSERT_EQ(nullptr, replayer_result.transformed_module);
  }
}

TEST(ReplayerTest, CheckFactsAfterReplay) {
  const std::string kTestShader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %8 = OpTypeInt 32 1
          %9 = OpTypePointer Function %8
         %50 = OpTypePointer Private %8
         %11 = OpConstant %8 1
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %10 = OpVariable %9 Function
               OpStore %10 %11
         %12 = OpFunctionCall %2 %6
               OpReturn
               OpFunctionEnd
          %6 = OpFunction %2 None %3
          %7 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  spvtools::ValidatorOptions validator_options;

  std::vector<uint32_t> binary_in;
  SpirvTools t(env);
  t.SetMessageConsumer(kConsoleMessageConsumer);
  ASSERT_TRUE(t.Assemble(kTestShader, &binary_in, kFuzzAssembleOption));
  ASSERT_TRUE(t.Validate(binary_in));

  protobufs::TransformationSequence transformations;
  *transformations.add_transformation() =
      TransformationAddConstantScalar(100, 8, {42}, true).ToMessage();
  *transformations.add_transformation() =
      TransformationAddGlobalVariable(101, 50, SpvStorageClassPrivate, 100,
                                      true)
          .ToMessage();
  *transformations.add_transformation() =
      TransformationAddParameter(6, 102, 8, {{12, 100}}, 103).ToMessage();
  *transformations.add_transformation() =
      TransformationAddSynonym(
          11,
          protobufs::TransformationAddSynonym::SynonymType::
              TransformationAddSynonym_SynonymType_COPY_OBJECT,
          104, MakeInstructionDescriptor(12, SpvOpFunctionCall, 0))
          .ToMessage();

  // Full replay
  protobufs::FactSequence empty_facts;
  auto replayer_result =
      Replayer(env, kConsoleMessageConsumer, binary_in, empty_facts,
               transformations, transformations.transformation_size(), true,
               validator_options)
          .Run();
  // Replay should succeed.
  ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete, replayer_result.status);
  // All transformations should be applied.
  ASSERT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
      transformations, replayer_result.applied_transformations));

  const std::string kExpected = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %8 = OpTypeInt 32 1
          %9 = OpTypePointer Function %8
         %50 = OpTypePointer Private %8
         %11 = OpConstant %8 1
        %100 = OpConstant %8 42
        %101 = OpVariable %50 Private %100
        %103 = OpTypeFunction %2 %8
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %10 = OpVariable %9 Function
               OpStore %10 %11
        %104 = OpCopyObject %8 %11
         %12 = OpFunctionCall %2 %6 %100
               OpReturn
               OpFunctionEnd
          %6 = OpFunction %2 None %103
        %102 = OpFunctionParameter %8
          %7 = OpLabel
               OpReturn
               OpFunctionEnd
  )";
  ASSERT_TRUE(
      IsEqual(env, kExpected, replayer_result.transformed_module.get()));

  ASSERT_TRUE(
      replayer_result.transformation_context->GetFactManager()->IdIsIrrelevant(
          100));
  ASSERT_TRUE(replayer_result.transformation_context->GetFactManager()
                  ->PointeeValueIsIrrelevant(101));
  ASSERT_TRUE(
      replayer_result.transformation_context->GetFactManager()->IdIsIrrelevant(
          102));
  ASSERT_TRUE(
      replayer_result.transformation_context->GetFactManager()->IsSynonymous(
          MakeDataDescriptor(11, {}), MakeDataDescriptor(104, {})));
}

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