// 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 <memory>
#include <string>
#include <utility>
#include <vector>

#include "src/ast/module.h"
#include "src/program.h"
#include "src/program_builder.h"

namespace tint {
namespace fuzzers {

[[noreturn]] void TintInternalCompilerErrorReporter(
    const tint::diag::List& diagnostics) {
  auto printer = tint::diag::Printer::create(stderr, true);
  tint::diag::Formatter{}.format(diagnostics, printer.get());
  __builtin_trap();
}

bool ExtractBindingRemapperInputs(const uint8_t** data,
                                  size_t* size,
                                  tint::transform::DataMap* inputs) {
  if ((*size) < sizeof(uint8_t)) {
    return false;
  }

  auto count = *reinterpret_cast<const uint8_t*>(*data);
  (*data) += sizeof(uint8_t);
  (*size) -= sizeof(uint8_t);

  struct Config {
    uint32_t old_group;
    uint32_t old_binding;
    uint32_t new_group;
    uint32_t new_binding;
    ast::AccessControl::Access new_ac;
  };

  if ((*size) < count * sizeof(Config)) {
    return false;
  }

  std::vector<Config> configs(count);

  memcpy(configs.data(), *data, count * sizeof(Config));

  (*data) += count * sizeof(Config);
  (*size) -= count * sizeof(Config);

  transform::BindingRemapper::BindingPoints binding_points;
  transform::BindingRemapper::AccessControls access_controls;
  for (const auto& config : configs) {
    binding_points[{config.old_binding, config.old_group}] = {
        config.new_binding, config.new_group};
    access_controls[{config.old_binding, config.old_group}] = config.new_ac;
  }

  inputs->Add<transform::BindingRemapper::Remappings>(binding_points,
                                                      access_controls);

  return true;
}

bool ExtractFirstIndexOffsetInputs(const uint8_t** data,
                                   size_t* size,
                                   tint::transform::DataMap* inputs) {
  struct Config {
    uint32_t group;
    uint32_t binding;
  };

  if ((*size) < sizeof(Config)) {
    return false;
  }

  Config config;
  memcpy(&config, data, sizeof(config));

  (*data) += sizeof(Config);
  (*size) -= sizeof(Config);

  inputs->Add<tint::transform::FirstIndexOffset::BindingPoint>(config.binding,
                                                               config.group);

  return true;
}

bool ExtractSingleEntryPointInputs(const uint8_t** data,
                                   size_t* size,
                                   tint::transform::DataMap* inputs) {
  if ((*size) < sizeof(uint8_t)) {
    return false;
  }

  auto count = *reinterpret_cast<const uint8_t*>(*data);
  (*data) += sizeof(uint8_t);
  (*size) -= sizeof(uint8_t);

  if ((*size) < count) {
    return false;
  }

  auto* c = reinterpret_cast<const char*>(*data);
  std::string input(c, c + count);

  (*data) += count * sizeof(char);
  (*size) -= count * sizeof(char);

  transform::SingleEntryPoint::Config cfg(input);
  inputs->Add<transform::SingleEntryPoint::Config>(cfg);

  return true;
}

CommonFuzzer::CommonFuzzer(InputFormat input, OutputFormat output)
    : input_(input),
      output_(output),
      transform_manager_(nullptr),
      inspector_enabled_(false) {}

CommonFuzzer::~CommonFuzzer() = default;

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

  Program program;

#if TINT_BUILD_WGSL_READER
  std::unique_ptr<Source::File> file;
#endif  // TINT_BUILD_WGSL_READER

  switch (input_) {
#if TINT_BUILD_WGSL_READER
    case InputFormat::kWGSL: {
      std::string str(reinterpret_cast<const char*>(data), size);

      file = std::make_unique<Source::File>("test.wgsl", str);
      program = reader::wgsl::Parse(file.get());
      break;
    }
#endif  // TINT_BUILD_WGSL_READER
#if TINT_BUILD_SPV_READER
    case InputFormat::kSpv: {
      size_t sizeInU32 = size / sizeof(uint32_t);
      const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
      std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);

      if (input.size() != 0) {
        program = reader::spirv::Parse(input);
      }
      break;
    }
#endif  // TINT_BUILD_WGSL_READER
    default:
      return 0;
  }

  if (output_ == OutputFormat::kNone) {
    return 0;
  }

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

  if (inspector_enabled_) {
    inspector::Inspector inspector(&program);

    auto entry_points = inspector.GetEntryPoints();
    if (inspector.has_error()) {
      return 0;
    }

    for (auto& ep : entry_points) {
      auto remapped_name = inspector.GetRemappedNameForEntryPoint(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto constant_ids = inspector.GetConstantIDs();
      if (inspector.has_error()) {
        return 0;
      }

      auto uniform_bindings =
          inspector.GetUniformBufferResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto storage_bindings =
          inspector.GetStorageBufferResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto readonly_bindings =
          inspector.GetReadOnlyStorageBufferResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto sampler_bindings = inspector.GetSamplerResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto comparison_sampler_bindings =
          inspector.GetComparisonSamplerResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto sampled_texture_bindings =
          inspector.GetSampledTextureResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }

      auto multisampled_texture_bindings =
          inspector.GetMultisampledTextureResourceBindings(ep.name);
      if (inspector.has_error()) {
        return 0;
      }
    }
  }

  if (transform_manager_) {
    auto out = transform_manager_->Run(&program, transform_inputs_);
    if (!out.program.IsValid()) {
      return 0;
    }

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

  std::unique_ptr<writer::Writer> writer;

  switch (output_) {
    case OutputFormat::kWGSL:
#if TINT_BUILD_WGSL_WRITER
      writer = std::make_unique<writer::wgsl::Generator>(&program);
#endif  // TINT_BUILD_WGSL_WRITER
      break;
    case OutputFormat::kSpv:
#if TINT_BUILD_SPV_WRITER
      writer = std::make_unique<writer::spirv::Generator>(&program);
#endif  // TINT_BUILD_SPV_WRITER
      break;
    case OutputFormat::kHLSL:
#if TINT_BUILD_HLSL_WRITER
      writer = std::make_unique<writer::hlsl::Generator>(&program);
#endif  // TINT_BUILD_HLSL_WRITER
      break;
    case OutputFormat::kMSL:
#if TINT_BUILD_MSL_WRITER
      writer = std::make_unique<writer::msl::Generator>(&program);
#endif  // TINT_BUILD_MSL_WRITER
      break;
    case OutputFormat::kNone:
      break;
  }

  if (writer) {
    writer->Generate();
  }

  return 0;
}

}  // namespace fuzzers
}  // namespace tint
