#pragma once

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

#include <util/generic/singleton.h>
#include <util/generic/vector.h>
#include <util/generic/yexception.h>
#include <util/string/printf.h>

namespace NWebmaster {

struct TArgs {
    static TArgs& Instance() {
        return *Singleton<TArgs>();
    }

public:
    TArgs()
        : _Argc(0)
        , _Argv(nullptr)
        , Initialized(false)
    {
    }

    static TArgs& CheckedInstance() {
        TArgs &args = Instance();

        if (!args.Initialized) {
            ythrow yexception() << "TArgs is not initialized";
        }

        return args;
    }

    static void Init(int argc, const char **argv) {
        const TString DefaultGlobalConfigPath = "/etc/yandex/webmaster/configs/wmconsole.development.properties";
        const TString DefaultLocalConfigPath = Sprintf("%s.development.properties", argv[0]);

        TArgs &args = Instance();
        args._Argc = argc;
        args._Argv = argv;
        args._Opts = NLastGetopt::TOpts::Default();

        args._Opts
            .AddLongOption('L', "log-path", "Log file location")
            .StoreResult(&args.LogPath)
            .RequiredArgument("<string>")
            .DefaultValue("");

        args._Opts
            .AddLongOption('C', "local-environment", "Local environment config (testing, development, production)")
            .StoreResult(&args.LocalConfigPath)
            .RequiredArgument("<string>")
            .DefaultValue(DefaultLocalConfigPath);

        args._Opts
            .AddLongOption('G', "global-environment", "Global environment config (testing, development, production)")
            .StoreResult(&args.GlobalConfigPath)
            .RequiredArgument("<string>")
            .DefaultValue(DefaultGlobalConfigPath);

        args.Initialized = true;
    }

    static int Argc() {
        return CheckedInstance()._Argc;
    }

    static const char **Argv() {
        return CheckedInstance()._Argv;
    }

    static NLastGetopt::TOpts &Opts() {
        return CheckedInstance()._Opts;
    }

    static THolder<NLastGetopt::TOptsParseResult> ParseOpts() {
        THolder<NLastGetopt::TOptsParseResult> args(new NLastGetopt::TOptsParseResult(&Opts(), Argc(), Argv()));
        return args;
    }

private:
    int _Argc;
    const char **_Argv;
    bool Initialized;
    NLastGetopt::TOpts _Opts;

public:
    TString GlobalConfigPath;
    TString LocalConfigPath;
    TString LogPath;
};

} //namespace NWebmaster
