#include "options.h"

#include <util/string/split.h>

void TOptions::BindToOpts(NLastGetopt::TOpts& opts) {
    opts.AddLongOption("manager", "type of snapshot manager: yt or zookeper")
        .RequiredArgument("MANAGER").StoreResult(&SnapshotManager)
        .DefaultValue(SnapshotManager);

    opts.AddLongOption("server", "snapshots server: YT proxy or ZooKeeper hosts")
        .RequiredArgument("SERVER").StoreResult(&SnapshotManagerContext.Server)
        .Required();

    opts.AddLongOption("path", "snapshots path: ypath or znode")
        .RequiredArgument("PATH").StoreResult(&SnapshotManagerContext.Path)
        .Required();

    opts.AddLongOption("token", "token to access YT or ZooKeeper")
        .RequiredArgument("TOKEN").StoreResult(&SnapshotManagerContext.Token);

    opts.AddLongOption("retry", "number of attempts")
        .RequiredArgument("COUNT").StoreResult(&SnapshotManagerContext.RetryOptions.RetryCount)
        .DefaultValue(::ToString(SnapshotManagerContext.RetryOptions.RetryCount));

    opts.AddLongOption("timestamp", "snapshot timestamp (default: latest available snapshot)")
        .RequiredArgument("TIMESTAMP").StoreResult(&Timestamp);

    opts.AddLongOption("shard", "shard id string, format: 'X-Y'")
        .RequiredArgument("SHARD").StoreResult(&ShardId);

    opts.AddLongOption("dst", "destination directory to fetch shard")
        .RequiredArgument("DST").StoreResult(&DstDir);

    opts.AddLongOption("verbose", "print progress to stderr")
        .NoArgument().StoreResult(&Verbose, true)
        .DefaultValue(Verbose ? "true" : "false");

    opts.SetFreeArgsNum(1);
    opts.SetFreeArgTitle(0, "COMMAND", "command: list_timestamps, list_shards, list_grouped_resources, fetch_shard");
}

void TOptions::PostProcess(TVector<TString> freeArgs) {
    Y_VERIFY(freeArgs.size() > 0);
    Command = ::FromString<ECommand>(freeArgs[0]);

    if (Command == ECommand::FetchShard || Command == ECommand::ListGroupedResources) {
        Y_VERIFY(!ShardId.empty(), "shard id is not set");
        Y_VERIFY(Command != ECommand::FetchShard || !DstDir.empty(), "destination directory is not set");

        auto s = StringSplitter(ShardId).Split('-').ToList<TStringBuf>();
        Y_VERIFY(s.size() == 2, "Incorrect shard id");
        ShardMin = ::FromString<ui64>(s.front());
        ShardMax = ::FromString<ui64>(s.back());
    }
}
