// Copyright 2020 The Tint Authors.
//
// 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 "gmock/gmock.h"
#include "src/reader/spirv/function.h"
#include "src/reader/spirv/parser_impl_test_helper.h"
#include "src/reader/spirv/spirv_tools_helpers_test.h"

namespace tint {
namespace reader {
namespace spirv {
namespace {

using ::testing::HasSubstr;

std::string Preamble() {
  return R"(
    OpCapability Shader
    OpMemoryModel Logical Simple
    OpEntryPoint Vertex %100 "x_100"
  )";
}

/// @returns a SPIR-V assembly segment which assigns debug names
/// to particular IDs.
std::string Names(std::vector<std::string> ids) {
  std::ostringstream outs;
  for (auto& id : ids) {
    outs << "    OpName %" << id << " \"" << id << "\"\n";
  }
  return outs.str();
}

std::string CommonTypes() {
  return R"(
    %void = OpTypeVoid
    %voidfn = OpTypeFunction %void
    %float = OpTypeFloat 32
    %uint = OpTypeInt 32 0
    %int = OpTypeInt 32 1
    %float_0 = OpConstant %float 0.0
  )";
}

std::string MainBody() {
  return R"(
    %100 = OpFunction %void None %voidfn
    %entry_100 = OpLabel
    OpReturn
    OpFunctionEnd
  )";
}

TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
  auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
     %100 = OpFunction %void None %voidfn
     %entry = OpLabel
     OpReturn
     OpFunctionEnd
  )"));
  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
  auto fe = p->function_emitter(100);
  EXPECT_TRUE(fe.Emit());
  auto got = p->program().to_str();
  std::string expect = R"(Module{
  Function x_100 -> __void
  ()
  {
    Return{}
  }
}
)";
  EXPECT_EQ(got, expect);
}

TEST_F(SpvParserTest, Emit_NonVoidResultType) {
  auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
     %fn_ret_float = OpTypeFunction %float
     %200 = OpFunction %float None %fn_ret_float
     %entry = OpLabel
     OpReturnValue %float_0
     OpFunctionEnd
  )" + MainBody()));
  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
  auto fe = p->function_emitter(200);
  EXPECT_TRUE(fe.Emit());

  auto got = p->program().to_str();
  std::string expect = R"(Module{
  Function x_200 -> __f32
  ()
  {
    Return{
      {
        ScalarConstructor[not set]{0.000000}
      }
    }
  }
}
)";
  EXPECT_THAT(got, HasSubstr(expect));
}

TEST_F(SpvParserTest, Emit_MixedParamTypes) {
  auto p = parser(
      test::Assemble(Preamble() + Names({"a", "b", "c"}) + CommonTypes() + R"(
     %fn_mixed_params = OpTypeFunction %void %uint %float %int

     %200 = OpFunction %void None %fn_mixed_params
     %a = OpFunctionParameter %uint
     %b = OpFunctionParameter %float
     %c = OpFunctionParameter %int
     %mixed_entry = OpLabel
     OpReturn
     OpFunctionEnd
  )" + MainBody()));
  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
  auto fe = p->function_emitter(200);
  EXPECT_TRUE(fe.Emit());

  auto got = p->program().to_str();
  std::string expect = R"(Module{
  Function x_200 -> __void
  (
    VariableConst{
      a
      none
      undefined
      __u32
    }
    VariableConst{
      b
      none
      undefined
      __f32
    }
    VariableConst{
      c
      none
      undefined
      __i32
    }
  )
  {
    Return{}
  }
}
)";
  EXPECT_THAT(got, HasSubstr(expect));
}

TEST_F(SpvParserTest, Emit_GenerateParamNames) {
  auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
     %fn_mixed_params = OpTypeFunction %void %uint %float %int

     %200 = OpFunction %void None %fn_mixed_params
     %14 = OpFunctionParameter %uint
     %15 = OpFunctionParameter %float
     %16 = OpFunctionParameter %int
     %mixed_entry = OpLabel
     OpReturn
     OpFunctionEnd
  )" + MainBody()));
  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
  auto fe = p->function_emitter(200);
  EXPECT_TRUE(fe.Emit());

  auto got = p->program().to_str();
  std::string expect = R"(Module{
  Function x_200 -> __void
  (
    VariableConst{
      x_14
      none
      undefined
      __u32
    }
    VariableConst{
      x_15
      none
      undefined
      __f32
    }
    VariableConst{
      x_16
      none
      undefined
      __i32
    }
  )
  {
    Return{}
  }
}
)";
  EXPECT_THAT(got, HasSubstr(expect));
}

}  // namespace
}  // namespace spirv
}  // namespace reader
}  // namespace tint
