// Copyright 2022 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/bench/benchmark.h"

#include <filesystem>
#include <sstream>
#include <utility>
#include <vector>

namespace tint::bench {
namespace {

std::filesystem::path kInputFileDir;

/// Copies the content from the file named `input_file` to `buffer`,
/// assuming each element in the file is of type `T`.  If any error occurs,
/// writes error messages to the standard error stream and returns false.
/// Assumes the size of a `T` object is divisible by its required alignment.
/// @returns true if we successfully read the file.
template <typename T>
std::variant<std::vector<T>, Error> ReadFile(const std::string& input_file) {
  FILE* file = nullptr;
#if defined(_MSC_VER)
  fopen_s(&file, input_file.c_str(), "rb");
#else
  file = fopen(input_file.c_str(), "rb");
#endif
  if (!file) {
    return Error{"Failed to open " + input_file};
  }

  fseek(file, 0, SEEK_END);
  const auto file_size = static_cast<size_t>(ftell(file));
  if (0 != (file_size % sizeof(T))) {
    std::stringstream err;
    err << "File " << input_file
        << " does not contain an integral number of objects: " << file_size
        << " bytes in the file, require " << sizeof(T) << " bytes per object";
    fclose(file);
    return Error{err.str()};
  }
  fseek(file, 0, SEEK_SET);

  std::vector<T> buffer;
  buffer.resize(file_size / sizeof(T));

  size_t bytes_read = fread(buffer.data(), 1, file_size, file);
  fclose(file);
  if (bytes_read != file_size) {
    return Error{"Failed to read " + input_file};
  }

  return buffer;
}

bool FindBenchmarkInputDir() {
  // Attempt to find the benchmark input files by searching up from the current
  // working directory.
  auto path = std::filesystem::current_path();
  while (std::filesystem::is_directory(path)) {
    auto test = path / "test" / "tint" / "benchmark";
    if (std::filesystem::is_directory(test)) {
      kInputFileDir = test;
      return true;
    }
    auto parent = path.parent_path();
    if (path == parent) {
      break;
    }
    path = parent;
  }
  return false;
}

}  // namespace

std::variant<tint::Source::File, Error> LoadInputFile(std::string name) {
  auto path = (kInputFileDir / name).string();
  auto data = ReadFile<uint8_t>(path);
  if (auto* buf = std::get_if<std::vector<uint8_t>>(&data)) {
    return tint::Source::File(path, std::string(buf->begin(), buf->end()));
  }
  return std::get<Error>(data);
}

std::variant<ProgramAndFile, Error> LoadProgram(std::string name) {
  auto res = bench::LoadInputFile(name);
  if (auto err = std::get_if<bench::Error>(&res)) {
    return *err;
  }
  auto& file = std::get<Source::File>(res);
  auto program = reader::wgsl::Parse(&file);
  if (program.Diagnostics().contains_errors()) {
    return Error{program.Diagnostics().str()};
  }
  return ProgramAndFile{std::move(program), std::move(file)};
}

}  // namespace tint::bench

int main(int argc, char** argv) {
  benchmark::Initialize(&argc, argv);
  if (benchmark::ReportUnrecognizedArguments(argc, argv)) {
    return 1;
  }
  if (!tint::bench::FindBenchmarkInputDir()) {
    std::cerr << "failed to locate benchmark input files" << std::endl;
    return 1;
  }
  benchmark::RunSpecifiedBenchmarks();
}
