// Copyright 2021 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 "fuzzers/tint_common_fuzzer.h"

#include <cassert>
#include <cstring>
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#if TINT_BUILD_SPV_READER
#include "spirv-tools/libspirv.hpp"
#endif  // TINT_BUILD_SPV_READER

#include "src/ast/module.h"
#include "src/diagnostic/formatter.h"
#include "src/program.h"
#include "src/utils/hash.h"

namespace tint {
namespace fuzzers {

namespace {

// A macro is used to avoid FATAL_ERROR creating its own stack frame. This leads
// to better de-duplication of bug reports, because ClusterFuzz only uses the
// top few stack frames for de-duplication, and a FATAL_ERROR stack frame
// provides no useful information.
#define FATAL_ERROR(diags, msg_string)                        \
  do {                                                        \
    std::string msg = msg_string;                             \
    auto printer = tint::diag::Printer::create(stderr, true); \
    if (!msg.empty()) {                                       \
      printer->write(msg + "\n", {diag::Color::kRed, true});  \
    }                                                         \
    tint::diag::Formatter().format(diags, printer.get());     \
    __builtin_trap();                                         \
  } while (false)

[[noreturn]] void TintInternalCompilerErrorReporter(
    const tint::diag::List& diagnostics) {
  FATAL_ERROR(diagnostics, "");
}

// Wrapping in a macro, so it can be a one-liner in the code, but not
// introduce another level in the stack trace. This will help with de-duping
// ClusterFuzz issues.
#define CHECK_INSPECTOR(program, inspector)                    \
  do {                                                         \
    if ((inspector).has_error()) {                             \
      if (!enforce_validity) {                                 \
        return;                                                \
      }                                                        \
      FATAL_ERROR((program)->Diagnostics(),                    \
                  "Inspector failed: " + (inspector).error()); \
    }                                                          \
  } while (false)

// Wrapping in a macro to make code more readable and help with issue de-duping.
#define VALIDITY_ERROR(diags, msg_string) \
  do {                                    \
    if (!enforce_validity) {              \
      return 0;                           \
    }                                     \
    FATAL_ERROR(diags, msg_string);       \
  } while (false)

bool SPIRVToolsValidationCheck(const tint::Program& program,
                               const std::vector<uint32_t>& spirv) {
  spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
  const tint::diag::List& diags = program.Diagnostics();
  tools.SetMessageConsumer([diags](spv_message_level_t, const char*,
                                   const spv_position_t& pos, const char* msg) {
    std::stringstream out;
    out << "Unexpected spirv-val error:\n"
        << (pos.line + 1) << ":" << (pos.column + 1) << ": " << msg
        << std::endl;

    auto printer = tint::diag::Printer::create(stderr, true);
    printer->write(out.str(), {diag::Color::kYellow, false});
    tint::diag::Formatter().format(diags, printer.get());
  });

  return tools.Validate(spirv.data(), spirv.size(),
                        spvtools::ValidatorOptions());
}

}  // namespace

void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options) {
  *options = b->build<writer::spirv::Options>();
}

void GenerateWgslOptions(DataBuilder* b, writer::wgsl::Options* options) {
  *options = b->build<writer::wgsl::Options>();
}

void GenerateHlslOptions(DataBuilder* b, writer::hlsl::Options* options) {
  *options = b->build<writer::hlsl::Options>();
}

void GenerateMslOptions(DataBuilder* b, writer::msl::Options* options) {
  *options = b->build<writer::msl::Options>();
}

CommonFuzzer::CommonFuzzer(InputFormat input, OutputFormat output)
    : input_(input), output_(output) {}

CommonFuzzer::~CommonFuzzer() = default;

int CommonFuzzer::Run(const uint8_t* data, size_t size) {
  tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);

#if TINT_BUILD_WGSL_WRITER
  tint::Program::printer = [](const tint::Program* program) {
    auto result = tint::writer::wgsl::Generate(program, {});
    if (!result.error.empty()) {
      return "error: " + result.error;
    }
    return result.wgsl;
  };
#endif  //  TINT_BUILD_WGSL_WRITER

  Program program;

#if TINT_BUILD_SPV_READER
  std::vector<uint32_t> spirv_input(size / sizeof(uint32_t));

#endif  // TINT_BUILD_SPV_READER

#if TINT_BUILD_WGSL_READER || TINT_BUILD_SPV_READER
  auto dump_input_data = [&](auto& content, const char* extension) {
    size_t hash = utils::Hash(content);
    auto filename = "fuzzer_input_" + std::to_string(hash) + extension;  //
    std::ofstream fout(filename, std::ios::binary);
    fout.write(reinterpret_cast<const char*>(data),
               static_cast<std::streamsize>(size));
    std::cout << "Dumped input data to " << filename << std::endl;
  };
#endif

  switch (input_) {
#if TINT_BUILD_WGSL_READER
    case InputFormat::kWGSL: {
      // Clear any existing diagnostics, as these will hold pointers to file_,
      // which we are about to release.
      diagnostics_ = {};
      std::string str(reinterpret_cast<const char*>(data), size);
      file_ = std::make_unique<Source::File>("test.wgsl", str);
      if (dump_input_) {
        dump_input_data(str, ".wgsl");
      }
      program = reader::wgsl::Parse(file_.get());
      break;
    }
#endif  // TINT_BUILD_WGSL_READER
#if TINT_BUILD_SPV_READER
    case InputFormat::kSpv: {
      // `spirv_input` has been initialized with the capacity to store `size /
      // sizeof(uint32_t)` uint32_t values. If `size` is not a multiple of
      // sizeof(uint32_t) then not all of `data` can be copied into
      // `spirv_input`, and any trailing bytes are discarded.
      std::memcpy(spirv_input.data(), data,
                  spirv_input.size() * sizeof(uint32_t));
      if (spirv_input.empty()) {
        return 0;
      }
      if (dump_input_) {
        dump_input_data(spirv_input, ".spv");
      }
      program = reader::spirv::Parse(spirv_input);
      break;
    }
#endif  // TINT_BUILD_SPV_READER
  }

  if (!program.IsValid()) {
    diagnostics_ = program.Diagnostics();
    return 0;
  }

#if TINT_BUILD_SPV_READER
  if (input_ == InputFormat::kSpv &&
      !SPIRVToolsValidationCheck(program, spirv_input)) {
    FATAL_ERROR(
        program.Diagnostics(),
        "Fuzzing detected invalid input spirv not being caught by Tint");
  }
#endif  // TINT_BUILD_SPV_READER

  RunInspector(&program);
  diagnostics_ = program.Diagnostics();

  if (transform_manager_) {
    auto out = transform_manager_->Run(&program, *transform_inputs_);
    if (!out.program.IsValid()) {
      // Transforms can produce error messages for bad input.
      // Catch ICEs and errors from non transform systems.
      for (const auto& diag : out.program.Diagnostics()) {
        if (diag.severity > diag::Severity::Error ||
            diag.system != diag::System::Transform) {
          VALIDITY_ERROR(program.Diagnostics(),
                         "Fuzzing detected valid input program being "
                         "transformed into an invalid output program");
        }
      }
    }

    program = std::move(out.program);
    RunInspector(&program);
  }

  switch (output_) {
    case OutputFormat::kWGSL: {
#if TINT_BUILD_WGSL_WRITER
      auto result = writer::wgsl::Generate(&program, options_wgsl_);
      generated_wgsl_ = std::move(result.wgsl);
      if (!result.success) {
        VALIDITY_ERROR(
            program.Diagnostics(),
            "WGSL writer errored on validated input:\n" + result.error);
      }
#endif  // TINT_BUILD_WGSL_WRITER
      break;
    }
    case OutputFormat::kSpv: {
#if TINT_BUILD_SPV_WRITER
      auto result = writer::spirv::Generate(&program, options_spirv_);
      generated_spirv_ = std::move(result.spirv);
      if (!result.success) {
        VALIDITY_ERROR(
            program.Diagnostics(),
            "SPIR-V writer errored on validated input:\n" + result.error);
      }

      if (!SPIRVToolsValidationCheck(program, generated_spirv_)) {
        VALIDITY_ERROR(program.Diagnostics(),
                       "Fuzzing detected invalid spirv being emitted by Tint");
      }

#endif  // TINT_BUILD_SPV_WRITER
      break;
    }
    case OutputFormat::kHLSL: {
#if TINT_BUILD_HLSL_WRITER
      auto result = writer::hlsl::Generate(&program, options_hlsl_);
      generated_hlsl_ = std::move(result.hlsl);
      if (!result.success) {
        VALIDITY_ERROR(
            program.Diagnostics(),
            "HLSL writer errored on validated input:\n" + result.error);
      }
#endif  // TINT_BUILD_HLSL_WRITER
      break;
    }
    case OutputFormat::kMSL: {
#if TINT_BUILD_MSL_WRITER
      auto result = writer::msl::Generate(&program, options_msl_);
      generated_msl_ = std::move(result.msl);
      if (!result.success) {
        VALIDITY_ERROR(
            program.Diagnostics(),
            "MSL writer errored on validated input:\n" + result.error);
      }
#endif  // TINT_BUILD_MSL_WRITER
      break;
    }
  }

  return 0;
}

void CommonFuzzer::RunInspector(Program* program) {
  inspector::Inspector inspector(program);
  diagnostics_ = program->Diagnostics();

  auto entry_points = inspector.GetEntryPoints();
  CHECK_INSPECTOR(program, inspector);

  auto constant_ids = inspector.GetConstantIDs();
  CHECK_INSPECTOR(program, inspector);

  auto constant_name_to_id = inspector.GetConstantNameToIdMap();
  CHECK_INSPECTOR(program, inspector);

  for (auto& ep : entry_points) {
    inspector.GetRemappedNameForEntryPoint(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetStorageSize(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetUniformBufferResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetStorageBufferResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetReadOnlyStorageBufferResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetSamplerResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetComparisonSamplerResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetSampledTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetMultisampledTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetWriteOnlyStorageTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetDepthTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetDepthMultisampledTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetExternalTextureResourceBindings(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetSamplerTextureUses(ep.name);
    CHECK_INSPECTOR(program, inspector);

    inspector.GetWorkgroupStorageSize(ep.name);
    CHECK_INSPECTOR(program, inspector);
  }
}

}  // namespace fuzzers
}  // namespace tint
