// 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/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" / "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();
}
