// 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.

#ifndef TEST_UNIT_SPIRV_H_
#define TEST_UNIT_SPIRV_H_

#include <stdint.h>

#include <iomanip>
#include <string>
#include <vector>

#include "gtest/gtest.h"
#include "source/assembly_grammar.h"
#include "source/binary.h"
#include "source/diagnostic.h"
#include "source/enum_set.h"
#include "source/opcode.h"
#include "source/spirv_endian.h"
#include "source/text.h"
#include "source/text_handler.h"
#include "source/val/validate.h"
#include "spirv-tools/libspirv.h"

#ifdef __ANDROID__
#include <sstream>
namespace std {
template <typename T>
std::string to_string(const T& val) {
  std::ostringstream os;
  os << val;
  return os.str();
}
}  // namespace std
#endif

// Determine endianness & predicate tests on it
enum {
  I32_ENDIAN_LITTLE = 0x03020100ul,
  I32_ENDIAN_BIG = 0x00010203ul,
};

static const union {
  unsigned char bytes[4];
  uint32_t value;
} o32_host_order = {{0, 1, 2, 3}};
#define I32_ENDIAN_HOST (o32_host_order.value)

// A namespace for utilities used in SPIR-V Tools unit tests.
namespace spvtest {

class WordVector;

// Emits the given word vector to the given stream.
// This function can be used by the gtest value printer.
void PrintTo(const WordVector& words, ::std::ostream* os);

// A proxy class to allow us to easily write out vectors of SPIR-V words.
class WordVector {
 public:
  explicit WordVector(const std::vector<uint32_t>& val) : value_(val) {}
  explicit WordVector(const spv_binary_t& binary)
      : value_(binary.code, binary.code + binary.wordCount) {}

  // Returns the underlying vector.
  const std::vector<uint32_t>& value() const { return value_; }

  // Returns the string representation of this word vector.
  std::string str() const {
    std::ostringstream os;
    PrintTo(*this, &os);
    return os.str();
  }

 private:
  const std::vector<uint32_t> value_;
};

inline void PrintTo(const WordVector& words, ::std::ostream* os) {
  size_t count = 0;
  const auto saved_flags = os->flags();
  const auto saved_fill = os->fill();
  for (uint32_t value : words.value()) {
    *os << "0x" << std::setw(8) << std::setfill('0') << std::hex << value
        << " ";
    if (count++ % 8 == 7) {
      *os << std::endl;
    }
  }
  os->flags(saved_flags);
  os->fill(saved_fill);
}

// Returns a vector of words representing a single instruction with the
// given opcode and operand words as a vector.
inline std::vector<uint32_t> MakeInstruction(
    spv::Op opcode, const std::vector<uint32_t>& args) {
  std::vector<uint32_t> result{
      spvOpcodeMake(uint16_t(args.size() + 1), opcode)};
  result.insert(result.end(), args.begin(), args.end());
  return result;
}

// Returns a vector of words representing a single instruction with the
// given opcode and whose operands are the concatenation of the two given
// argument lists.
inline std::vector<uint32_t> MakeInstruction(
    spv::Op opcode, std::vector<uint32_t> args,
    const std::vector<uint32_t>& extra_args) {
  args.insert(args.end(), extra_args.begin(), extra_args.end());
  return MakeInstruction(opcode, args);
}

// Returns the vector of words representing the concatenation
// of all input vectors.
inline std::vector<uint32_t> Concatenate(
    const std::vector<std::vector<uint32_t>>& instructions) {
  std::vector<uint32_t> result;
  for (const auto& instruction : instructions) {
    result.insert(result.end(), instruction.begin(), instruction.end());
  }
  return result;
}

// A type for easily creating spv_text_t values, with an implicit conversion to
// spv_text.
struct AutoText {
  explicit AutoText(const std::string& value)
      : str(value), text({str.data(), str.size()}) {}
  operator spv_text() { return &text; }
  std::string str;
  spv_text_t text;
};

// An example case for an enumerated value, optionally with operands.
template <typename E>
class EnumCase {
 public:
  EnumCase() = default;  // Required by ::testing::Combine().
  EnumCase(E val, std::string enum_name, std::vector<uint32_t> ops = {})
      : enum_value_(val), name_(enum_name), operands_(ops) {}
  // Returns the enum value as a uint32_t.
  uint32_t value() const { return static_cast<uint32_t>(enum_value_); }
  // Returns the name of the enumerant.
  const std::string& name() const { return name_; }
  // Returns a reference to the operands.
  const std::vector<uint32_t>& operands() const { return operands_; }

 private:
  E enum_value_;
  std::string name_;
  std::vector<uint32_t> operands_;
};

// Returns a string with num_4_byte_chars Unicode characters,
// each of which has a 4-byte UTF-8 encoding.
inline std::string MakeLongUTF8String(size_t num_4_byte_chars) {
  // An example of a longest valid UTF-8 character.
  // Be explicit about the character type because Microsoft compilers can
  // otherwise interpret the character string as being over wide (16-bit)
  // characters.  Ideally, we would just use a C++11 UTF-8 string literal,
  // but we want to support older Microsoft compilers.
  const std::basic_string<char> earth_africa("\xF0\x9F\x8C\x8D");
  EXPECT_EQ(4u, earth_africa.size());

  std::string result;
  result.reserve(num_4_byte_chars * 4);
  for (size_t i = 0; i < num_4_byte_chars; i++) {
    result += earth_africa;
  }
  EXPECT_EQ(4 * num_4_byte_chars, result.size());
  return result;
}

// Returns a vector of all valid target environment enums.
inline std::vector<spv_target_env> AllTargetEnvironments() {
  return {
      SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
      SPV_ENV_OPENCL_1_2,    SPV_ENV_OPENCL_EMBEDDED_1_2,
      SPV_ENV_OPENCL_2_0,    SPV_ENV_OPENCL_EMBEDDED_2_0,
      SPV_ENV_OPENCL_2_1,    SPV_ENV_OPENCL_EMBEDDED_2_1,
      SPV_ENV_OPENCL_2_2,    SPV_ENV_OPENCL_EMBEDDED_2_2,
      SPV_ENV_VULKAN_1_0,    SPV_ENV_OPENGL_4_0,
      SPV_ENV_OPENGL_4_1,    SPV_ENV_OPENGL_4_2,
      SPV_ENV_OPENGL_4_3,    SPV_ENV_OPENGL_4_5,
      SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3,
      SPV_ENV_VULKAN_1_1,
  };
}

// Returns the capabilities in a CapabilitySet as an ordered vector.
inline std::vector<spv::Capability> ElementsIn(
    const spvtools::CapabilitySet& capabilities) {
  return std::vector<spv::Capability>(capabilities.cbegin(),
                                      capabilities.cend());
}

}  // namespace spvtest
#endif  // TEST_UNIT_SPIRV_H_
