#pragma once

#include <algorithm>
#include <iostream>
#include <optional>
#include <span>
#include <string>

// expects options of .*name=value
int getOption(int argc, char *argv[], const std::string &name, std::optional<int> value_if_not_found = {}) {
  for (char *option: std::span(argv + 1, argc - 1)) {
    auto option_str = std::string(option);
    auto pos = option_str.find(name);
    if (pos == std::string::npos || pos + name.size() >= option_str.size()) {
      continue;
    }
    auto value = option_str.substr(pos + name.size() + 1);
    if (value.empty() || value.size() > 9U || !std::ranges::all_of(value, [](char ch) { return isdigit(ch); })) {
      std::cerr << "Option " << name << ", expected int value, got \"" << value << "\"\n";
      exit(12);
    }
    return static_cast<int>(strtoll(value.c_str(), nullptr, 10));
  }
  if (value_if_not_found.has_value()) {
    return *value_if_not_found;
  }
  std::cerr << "Expected option \"" << name << "\", but didn't find it.\n";
  exit(11);
}
