#include "local_indexer.h"
#include "yt_indexer.h"

#include <ysite/yandex/common/global_indexer_flags.h>

#include <library/cpp/getopt/last_getopt.h>
#include <library/cpp/getopt/modchooser.h>
#include <library/cpp/logger/global/global.h>

#include <util/generic/yexception.h>
#include <util/string/vector.h>
#include <util/system/env.h>

int RunLocal(int argc, const char** argv);
int RunYT(int argc, const char** argv);
bool HasVerboseOption(int argc, const char** argv);

int main(int argc, char** argv) {
    if (!GetEnv("YT_LOG_LEVEL")) {
        const bool ytVerbose = HasVerboseOption(argc, const_cast<const char**>(argv));
        SetEnv("YT_LOG_LEVEL", ytVerbose ? "INFO" : "WARNING");
    }
    TGlobalIndexerFlags::SetNumbersStyleNoZeros(true);
    NYT::Initialize(argc, const_cast<const char**>(argv));
    InitGlobalLog2Console();

    TModChooser modChooser;
    modChooser.AddMode("local", RunLocal, "index local documents");
    modChooser.AddMode("yt", RunYT, "index documents from YT table");

    return modChooser.Run(argc, const_cast<const char**>(argv));
}

int RunLocal(int argc, const char** argv) {
    try {
        TDaemonOptions daemonOptions;
        TLocalIndexer::TOptions options;
        NLastGetopt::TOpts opts;
        opts.AddHelpOption('?');
        opts.AddVersionOption('v');
        daemonOptions.BindToOpts(opts);
        options.BindToOpts(opts);

        NLastGetopt::TOptsParseResultException res(&opts, argc, argv);
        daemonOptions.SetConfigFileName(res.GetFreeArgs()[0]);
        TString configText = daemonOptions.RunPreprocessor();

        TLocalIndexer ind(configText, options);
        ind.Run();
    } catch (const yexception& e) {
        FATAL_LOG << "Local indexing failed: " << e.what() << Endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

int RunYT(int argc, const char** argv) {
    try {
        TYTIndexer indexer(argc, argv);
        indexer.Run();
    } catch (...) {
        const TString message = CurrentExceptionMessage();
        InitGlobalLog2Console();
        FATAL_LOG << "YT indexing failed: " << message << Endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

bool HasVerboseOption(int argc, const char** argv) {
    // We have to use an ad-hoc loop, because NYT::Initialize is called before ModChooser.
    constexpr TStringBuf verbose = "--verbose";
    for (int i = 1; i < argc; ++i) {
        if (argv[i] == verbose)
            return true;
    }
    return false;
}
