// 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 "src/tint/writer/spirv/test_helper.h"

namespace tint {
namespace writer {
namespace spirv {
namespace {

using BinaryWriterTest = TestHelper;

TEST_F(BinaryWriterTest, Preamble) {
  BinaryWriter bw;
  bw.WriteHeader(5);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 5u);
  EXPECT_EQ(res[0], spv::MagicNumber);
  EXPECT_EQ(res[1], 0x00010300u);  // SPIR-V 1.3
  EXPECT_EQ(res[2], 23u << 16);    // Generator ID
  EXPECT_EQ(res[3], 5u);           // ID Bound
  EXPECT_EQ(res[4], 0u);           // Reserved
}

TEST_F(BinaryWriterTest, Float) {
  spirv::Builder& b = Build();

  b.push_annot(spv::Op::OpKill, {Operand::Float(2.4f)});
  BinaryWriter bw;
  bw.WriteBuilder(&b);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 2u);
  float f;
  memcpy(&f, res.data() + 1, 4);
  EXPECT_EQ(f, 2.4f);
}

TEST_F(BinaryWriterTest, Int) {
  spirv::Builder& b = Build();

  b.push_annot(spv::Op::OpKill, {Operand::Int(2)});
  BinaryWriter bw;
  bw.WriteBuilder(&b);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 2u);
  EXPECT_EQ(res[1], 2u);
}

TEST_F(BinaryWriterTest, String) {
  spirv::Builder& b = Build();

  b.push_annot(spv::Op::OpKill, {Operand::String("my_string")});
  BinaryWriter bw;
  bw.WriteBuilder(&b);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 4u);

  uint8_t* v = reinterpret_cast<uint8_t*>(res.data() + 1);
  EXPECT_EQ(v[0], 'm');
  EXPECT_EQ(v[1], 'y');
  EXPECT_EQ(v[2], '_');
  EXPECT_EQ(v[3], 's');
  EXPECT_EQ(v[4], 't');
  EXPECT_EQ(v[5], 'r');
  EXPECT_EQ(v[6], 'i');
  EXPECT_EQ(v[7], 'n');
  EXPECT_EQ(v[8], 'g');
  EXPECT_EQ(v[9], '\0');
  EXPECT_EQ(v[10], '\0');
  EXPECT_EQ(v[11], '\0');
}

TEST_F(BinaryWriterTest, String_Multiple4Length) {
  spirv::Builder& b = Build();

  b.push_annot(spv::Op::OpKill, {Operand::String("mystring")});
  BinaryWriter bw;
  bw.WriteBuilder(&b);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 4u);

  uint8_t* v = reinterpret_cast<uint8_t*>(res.data() + 1);
  EXPECT_EQ(v[0], 'm');
  EXPECT_EQ(v[1], 'y');
  EXPECT_EQ(v[2], 's');
  EXPECT_EQ(v[3], 't');
  EXPECT_EQ(v[4], 'r');
  EXPECT_EQ(v[5], 'i');
  EXPECT_EQ(v[6], 'n');
  EXPECT_EQ(v[7], 'g');
  EXPECT_EQ(v[8], '\0');
  EXPECT_EQ(v[9], '\0');
  EXPECT_EQ(v[10], '\0');
  EXPECT_EQ(v[11], '\0');
}

TEST_F(BinaryWriterTest, TestInstructionWriter) {
  Instruction i1{spv::Op::OpKill, {Operand::Int(2)}};
  Instruction i2{spv::Op::OpKill, {Operand::Int(4)}};

  BinaryWriter bw;
  bw.WriteInstruction(i1);
  bw.WriteInstruction(i2);

  auto res = bw.result();
  ASSERT_EQ(res.size(), 4u);
  EXPECT_EQ(res[1], 2u);
  EXPECT_EQ(res[3], 4u);
}

}  // namespace
}  // namespace spirv
}  // namespace writer
}  // namespace tint
