#include <fstream>
#include <iostream>
#include <string>

#include <args.hxx>

#include "common.hh"


namespace param {
using namespace ::args;

ArgumentParser parser {
  "converter: feature code probability matrix -> feature code"
};
HelpFlag help {
  parser, "help", "display this menu", {'h', "help"},
};

ValueFlag<std::string> smap {
  parser, "path", "step map file path", {"smap"},
};

ValueFlag<size_t> fcnum {
  parser, "50", "number of fcode alphabet", {"fc-num"}, 50
};

}  // namespace param


static void Exec() {
  const auto fcnum = args::get(param::fcnum);
  Enforce(fcnum > 0, "fc-num must be greater than 0");

  std::ifstream smap_st {args::get(param::smap)};
  Enforce(!!smap_st, "smap path is invalid");
  const auto smap = ReadMatrix<uint32_t>(smap_st);
  Enforce(smap.size() > 0 && smap[0].size() > 0, "empty smap");

  const auto bn = smap[0].size();
  for (auto& br : smap) {
    Enforce(br.size() == bn, "all node should have the same number of branch");
  }

  size_t fcode_p, dcode;
  std::cin >> fcode_p;
  for (size_t fcode, t = 0; std::cin >> fcode; ++t) {
    Enforce(fcode < fcnum, "fcode overflow");
    Enforce(fcnum*(t+1) <= smap.size(), "smap row shortage");

    const auto& row = smap[t*fcnum + fcode_p];
    auto itr = std::find(row.begin(), row.end(), fcode);
    Enforce(itr != row.end(), "invalid step detected");
    std::cout << std::distance(row.begin(), itr) << '\n';
    fcode_p = fcode;
  }
}

int main(int argc, char** argv)
try {
  param::parser.ParseCLI(argc, argv);
  Exec();
  return EXIT_SUCCESS;
} catch (const args::Help&) {
  std::cout << param::parser << std::endl;
  return EXIT_SUCCESS;
} catch (const std::exception& e) {
  std::cerr << e.what() << std::endl;
  return EXIT_FAILURE;
}