// 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_TEST_FIXTURE_H_
#define TEST_TEST_FIXTURE_H_

#include <string>
#include <vector>

#include "test/unit_spirv.h"

namespace spvtest {

// RAII for spv_context.
struct ScopedContext {
  ScopedContext(spv_target_env env = SPV_ENV_UNIVERSAL_1_0)
      : context(spvContextCreate(env)) {}
  ~ScopedContext() { spvContextDestroy(context); }
  spv_context context;
};

// Common setup for TextToBinary tests. SetText() should be called to populate
// the actual test text.
template <typename T>
class TextToBinaryTestBase : public T {
 public:
  // Shorthand for SPIR-V compilation result.
  using SpirvVector = std::vector<uint32_t>;

  // Offset into a SpirvVector at which the first instruction starts.
  static const SpirvVector::size_type kFirstInstruction = 5;

  TextToBinaryTestBase() : diagnostic(nullptr), text(), binary(nullptr) {
    char textStr[] = "substitute the text member variable with your test";
    text = {textStr, strlen(textStr)};
  }

  virtual ~TextToBinaryTestBase() {
    DestroyBinary();
    if (diagnostic) spvDiagnosticDestroy(diagnostic);
  }

  // Returns subvector v[from:end).
  SpirvVector Subvector(const SpirvVector& v, SpirvVector::size_type from) {
    assert(from <= v.size());
    return SpirvVector(v.begin() + from, v.end());
  }

  // Compiles SPIR-V text in the given assembly syntax format, asserting
  // compilation success. Returns the compiled code.
  SpirvVector CompileSuccessfully(const std::string& txt,
                                  spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
    spv_result_t status =
        spvTextToBinary(ScopedContext(env).context, txt.c_str(), txt.size(),
                        &binary, &diagnostic);
    EXPECT_EQ(SPV_SUCCESS, status) << txt;
    SpirvVector code_copy;
    if (status == SPV_SUCCESS) {
      code_copy = SpirvVector(binary->code, binary->code + binary->wordCount);
      DestroyBinary();
    } else {
      spvDiagnosticPrint(diagnostic);
    }
    return code_copy;
  }

  // Compiles SPIR-V text with the given format, asserting compilation failure.
  // Returns the error message(s).
  std::string CompileFailure(const std::string& txt,
                             spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
    EXPECT_NE(SPV_SUCCESS,
              spvTextToBinary(ScopedContext(env).context, txt.c_str(),
                              txt.size(), &binary, &diagnostic))
        << txt;
    DestroyBinary();
    return diagnostic->error;
  }

  // Encodes SPIR-V text into binary and then decodes the binary using
  // given options. Returns the decoded text.
  std::string EncodeAndDecodeSuccessfully(
      const std::string& txt,
      uint32_t disassemble_options = SPV_BINARY_TO_TEXT_OPTION_NONE,
      spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
    DestroyBinary();
    ScopedContext context(env);
    disassemble_options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER;
    spv_result_t error = spvTextToBinary(context.context, txt.c_str(),
                                         txt.size(), &binary, &diagnostic);
    if (error) {
      spvDiagnosticPrint(diagnostic);
      spvDiagnosticDestroy(diagnostic);
    }
    EXPECT_EQ(SPV_SUCCESS, error);
    if (!binary) return "";

    spv_text decoded_text;
    error = spvBinaryToText(context.context, binary->code, binary->wordCount,
                            disassemble_options, &decoded_text, &diagnostic);
    if (error) {
      spvDiagnosticPrint(diagnostic);
      spvDiagnosticDestroy(diagnostic);
    }
    EXPECT_EQ(SPV_SUCCESS, error) << txt;

    const std::string decoded_string = decoded_text->str;
    spvTextDestroy(decoded_text);

    return decoded_string;
  }

  // Encodes SPIR-V text into binary. This is expected to succeed.
  // The given words are then appended to the binary, and the result
  // is then decoded. This is expected to fail.
  // Returns the error message.
  std::string EncodeSuccessfullyDecodeFailed(
      const std::string& txt, const SpirvVector& words_to_append) {
    SpirvVector code =
        spvtest::Concatenate({CompileSuccessfully(txt), words_to_append});

    spv_text decoded_text;
    EXPECT_NE(SPV_SUCCESS,
              spvBinaryToText(ScopedContext().context, code.data(), code.size(),
                              SPV_BINARY_TO_TEXT_OPTION_NONE, &decoded_text,
                              &diagnostic));
    if (diagnostic) {
      std::string error_message = diagnostic->error;
      spvDiagnosticDestroy(diagnostic);
      diagnostic = nullptr;
      return error_message;
    }
    return "";
  }

  // Compiles SPIR-V text, asserts success, and returns the words representing
  // the instructions.  In particular, skip the words in the SPIR-V header.
  SpirvVector CompiledInstructions(const std::string& txt,
                                   spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
    const SpirvVector code = CompileSuccessfully(txt, env);
    SpirvVector result;
    // Extract just the instructions.
    // If the code fails to compile, then return the empty vector.
    // In any case, don't crash or invoke undefined behaviour.
    if (code.size() >= kFirstInstruction)
      result = Subvector(code, kFirstInstruction);
    return result;
  }

  void SetText(const std::string& code) {
    textString = code;
    text.str = textString.c_str();
    text.length = textString.size();
  }

  // Destroys the binary, if it exists.
  void DestroyBinary() {
    spvBinaryDestroy(binary);
    binary = nullptr;
  }

  spv_diagnostic diagnostic;

  std::string textString;
  spv_text_t text;
  spv_binary binary;
};

using TextToBinaryTest = TextToBinaryTestBase<::testing::Test>;
}  // namespace spvtest

using RoundTripTest =
    spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>;

#endif  // TEST_TEST_FIXTURE_H_
