/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <stdio.h>
#include <string.h>
#include <fstream>
#include <iostream>
#include <optional>
#include <sstream>
#include <unordered_map>

#include "se_defines.h"

SE_GLOBALS()

class EffectiveLookup {
  uint32_t seed;
  std::unordered_map<uint32_t, std::unordered_map<char, uint32_t>> set_entries;
  std::unordered_map<uint32_t, std::string> names;

 public:
  bool valid;

  EffectiveLookup() : seed(0), valid(true) {}
  void insert(uint32_t key, char nseed, uint32_t value) {
    set_entries[key][nseed] = value;
  }
  void insert_value(uint32_t key, std::string val) {
    names[key] = val;
  }

  std::optional<std::string> lookup(char x) {
    if (!valid) {
      return std::nullopt;
    }
    auto table = set_entries.find(seed);
    if (table == set_entries.end()) {
      valid = false;
      return std::nullopt;
    }
    SE_STEP(true);
    auto new_seed = table->second.find(x);
    if (new_seed == table->second.end()) {
      valid = false;
      return std::nullopt;
    }
    SE_STEP(true);
    seed = new_seed->second;
    if (names.find(seed) != names.end()) {
      SE_STEP(true);
      return names[seed];
    }
    return std::nullopt;
  }
};

void test_case(std::string str) {
  std::optional<std::string> result = std::nullopt;
  EffectiveLookup hashset;
  hashset.insert(0, 'a', 1);
  hashset.insert(1, 'b', 2);
  hashset.insert(2, 'c', 3);
  hashset.insert_value(3, "expected");
  for (char c : str) {
    result = hashset.lookup(c);
    if (!hashset.valid) {
      break;
    }
  }
  if (result.has_value()) {
    SE_TARGET_STATE((*result == "expected"));
  }
}

int main(int argc, char* argv[]) {
  std::istream* input;
  std::ifstream file;
  if (argc < 2) {
    input = &std::cin; // No file name provided, read from stdin
  } else {
    file.open(argv[1]);
    if (!file) {
      std::cerr << "Could not open the file.\n";
      return 1;
    }
    input = &file; // File opened successfully, read from file
  }
  std::string content(
      (std::istreambuf_iterator<char>(*input)),
      std::istreambuf_iterator<char>());
  test_case(content.c_str());
  return 0;
}
