#include <saas/api/action.h>

#include <saas/library/indexer_protocol/sender_neh.h>
#include <saas/protos/reply.pb.h>
#include <saas/protos/rtyserver.pb.h>

#include <library/cpp/getopt/small/last_getopt.h>
#include <library/cpp/json/json_reader.h>

#include <util/datetime/base.h>
#include <util/generic/yexception.h>
#include <util/stream/input.h>
#include <util/stream/output.h>
#include <util/string/cast.h>
#include <util/string/vector.h>

struct TConfig {
    TString Host;
    ui16 Port = 0;

    void Print(IOutputStream& out) {
        out << "--- Config ---\n";
        out << "Host: " << Host << '\n';
        out << "Port: " << Port << '\n';
        out << "---" << Endl;
    }

    void Init(int argc, const char* argv[]) {
        auto makeOpt = [](TString name, TString help, bool required = true) {
            NLastGetopt::TOpt opt;
            opt.AddLongName(name);
            opt.Help(help);
            if (required) {
                opt.Required();
            }
            return opt;
        };
        TString hostString;
        NLastGetopt::TOpts opts;
        opts.AddOption(makeOpt("host", "target domain:port").StoreResult(&hostString));
        opts.AddHelpOption('h');
        {
            NLastGetopt::TOptsParseResult parser(&opts, argc, argv);
        }
        TVector<TString> hostParts = SplitString(hostString, ":");
        Y_ENSURE(hostParts.size() == 2);
        Host = hostParts[0];
        Port = FromString<ui16>(hostParts[1]);
    }
};

bool IndexAction(const TString& host, ui16 port, const NSaas::TAction& action) {
    NRTYServer::TNehSender sender(host, port);
    auto context = sender.Send(action.ToProtobuf());
    if (!context) {
        Cerr << "no context" << Endl;
        return false;
    }
    NRTYServer::TReply reply;
    if (!sender.Recv(context, reply, TDuration::Seconds(10))) {
        Cerr << "no reply" << Endl;
        return false;
    }
    Cout << "Status: " << reply.GetStatus() << '\n';
    Cout << "StatusMessage: " << reply.GetStatusMessage() << Endl;
    return true;
}

int main(int argc, const char* argv[]) {
    try {
        TConfig config;
        config.Init(argc, argv);
        config.Print(Cout);

        size_t actionId = 1;
        for (TString jsonStr; Cin.ReadLine(jsonStr);) {
            NSaas::TAction action;
            action.ParseFromJson(NJson::ReadJsonFastTree(jsonStr, /* notClosedBracketIsError = */ true));
            action.SetId(actionId++);
            if (action.HasDocument()) {
                if (!action.GetDocument().HasTimestamp()) {
                    action.GetDocument().SetTimestamp(Now().Seconds());
                }
            }

            bool result = IndexAction(config.Host, config.Port, action);
            if (!result) {
                Cerr << "IndexAction failed" << Endl;
                return 2;
            }
        }
        return 0;

    } catch (...) {
        Cerr << CurrentExceptionMessage() << Endl;
        return 1;
    }
}

