#include "main.h"

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

using NLastGetopt::TOpt;
using NLastGetopt::TOpts;
using NLastGetopt::TOptsParseResult;

void RunMain(int argc, char **argv) {
    TCaptureOptions options;
    TOpts opts = TOpts::Default();

    opts.AddLongOption('c', "client", "send packets to remote server")
        .SetFlag(&options.clientMode).NoArgument();

    opts.AddLongOption('i', "interface", "interface for capturing")
        .StoreResult(&options.iface).RequiredArgument();
    opts.AddLongOption('f', "filter", "pcap filter")
        .StoreResult(&options.filter).RequiredArgument();
    opts.AddLongOption('r', "remote-server", "remote server for storing packets")
        .StoreResult(&options.remoteServer).RequiredArgument();
    opts.AddLongOption('t', "threads", "thread count")
        .StoreResult(&options.threadCount).RequiredArgument()
        .DefaultValue(1);
    opts.AddLongOption('l', "packets-limit", "stop capturing after n packets")
        .StoreResult(&options.numberOfPackets).RequiredArgument()
        .DefaultValue(0);
    opts.AddLongOption('s', "snap-size", "snapshot size")
        .StoreResult(&options.snapSize).RequiredArgument()
        .DefaultValue(262144);
    opts.AddLongOption('b', "buffer-size", "buffer size")
        .StoreResult(&options.bufferSize).RequiredArgument()
        .DefaultValue(2097152);
    opts.AddLongOption('d', "bind", "bind to address for receiving packets")
        .StoreResult(&options.bind).RequiredArgument();
    opts.AddLongOption('o', "output", "output pcap file")
        .StoreResult(&options.output).RequiredArgument();
    opts.AddLongOption("timeout", "grpc client connection timeout(seconds)")
        .StoreResult(&options.timeout).RequiredArgument()
        .DefaultValue(5);
    opts.AddLongOption("link-type", "link type[default: 1 - DLT_EN10MB]. for Linux any interface: DLT_LINUX_SLL - 113")
        .StoreResult(&options.linkType).RequiredArgument()
        .DefaultValue(DLT_EN10MB);

    TOptsParseResult res(&opts, argc, argv);

#if not defined(_linux_)
    if (options.clientMode && options.threadCount > 1) {
        Cerr << "Multithreaded capturing is available only on Linux\n";
        options.threadCount = 1;
    }
#endif

    if (options.clientMode)
        RunMainClient(options);
    else
        RunMainServer(options);

}

int main(int argc, char** argv) noexcept {
    try {
        RunMain(argc, argv);
    } catch (const yexception& e) {
        Cerr << e.what() << "\n";
        return 1;
    } catch (...) {
        return 1;
    }
}
