#include <balancer/modules/exp_static/calc/calc.h>

#include <library/cpp/getopt/last_getopt.h>

#include <util/string/strip.h>

int main(int argc, const char** argv) {
    using namespace NModExpStatic;
    using namespace NSrvKernel;

    TExpConf conf;
    TExpRate rate;

    auto opts = NLastGetopt::TOpts::Default();
    opts.SetTitle("Get exp slot by ip (reads ips from stdin)");
    opts.AddLongOption("salt").RequiredArgument("SALT").DefaultValue(conf.Salt).StoreResult(&conf.Salt);
    opts.AddLongOption("slots").RequiredArgument("SLOTS").DefaultValue(conf.SlotsCount).StoreResult(&conf.SlotsCount);
    opts.AddLongOption("buckets").RequiredArgument("BUCKETS").DefaultValue(conf.BucketsCount).StoreResult(&conf.BucketsCount);
    opts.AddLongOption('r', "rate").RequiredArgument("RATE").Required().StoreResult(&rate);

    opts.SetFreeArgsMin(0);
    opts.SetFreeArgsMax(0);

    NLastGetopt::TOptsParseResult(&opts, argc, argv);

    const TString salt = GenCombinedSalt(conf, rate);

    TString line;
    while (Cin.ReadLine(line)) {
        TStringBuf lineIt = line;
        if (auto ip = lineIt.NextTok('\t')) {
            auto res = NModExpStatic::CalcExpByIp(conf, rate, salt, TIpAddr::FromIp(TString(ip)).GetOrThrow());
            Cout << ip << '\t' << res.Type << '\t' << res.Bucket;
            if (line) {
                Cout << '\t' << lineIt;
            }
            Cout << Endl;
        }
    }
}
