#include <buildboxcommon_commandline.h>
#include <buildboxworker_cmdlinespec.h>
#include <buildboxworker_worker.h>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace buildboxworker;
using namespace testing;

class ParserTestWorker : public Worker {
  public:
    ParserTestWorker(const buildboxcommon::CommandLine &commandLine,
                     const std::string &botId,
                     buildboxcommon::buildboxcommonmetrics::MetricsConfigType
                         *metricsConfig)
        : Worker(commandLine, botId, metricsConfig)
    {
    }
    void tester()
    {
        EXPECT_STREQ("dev", d_botsServer.d_instanceName.c_str());
        EXPECT_EQ("http://127.0.0.1:50011", d_casServer.d_url);
        EXPECT_EQ("http://100.70.37.178:50051", d_botsServer.d_url);
        EXPECT_STREQ("debug", d_logLevel.c_str());
        EXPECT_EQ("4", d_botsServer.d_retryLimit);
        EXPECT_EQ("1000", d_botsServer.d_retryDelay);
        EXPECT_EQ("4", d_casServer.d_retryLimit);
        EXPECT_EQ("1000", d_casServer.d_retryDelay);
        EXPECT_EQ("http://127.0.0.1:8080", d_assetServer.d_url);
        EXPECT_EQ("asset-instance", d_assetServer.d_instanceName);
        EXPECT_EQ("5", d_assetServer.d_retryLimit);
        EXPECT_EQ("2000", d_assetServer.d_retryDelay);
        EXPECT_EQ("/opt/remoteexecution/buildbox-run-hosttools",
                  d_runnerCommand);
        EXPECT_THAT(
            d_extraRunArgs,
            ElementsAre("--prefix-staged-dir", "--use-localcas",
                        "--userchroot-bin=/bb/dbldroot/bin/userchroot"));
        EXPECT_THAT(d_platform,
                    ElementsAre(Pair("OSFamily", "linux"),
                                Pair("ISA", "x86-64"),
                                Pair("chrootRootDigest",
                                     "8533ec9ba7494cc8295ccd0bfdca08457421a28b"
                                     "4e92c8eb18e7178fb400f5d4/930"),
                                Pair("chrootRootDigest",
                                     "1e7088e7aca9e8713a84122218a89c8908b39b57"
                                     "97d32170f1afa6e474b9ade6/930")));
        EXPECT_THAT(d_diskUsageChecks,
                    ElementsAre(Pair("/tmp", 90), Pair("/var/cache", 85)));
        EXPECT_STREQ(
            "/dbldroot/data/chroot/buildboxworker-1/opt/remoteexecution/"
            "buildboxworker.conf",
            d_configFileName.c_str());
        EXPECT_EQ(std::chrono::seconds(15), maxWaitTime());
        EXPECT_EQ(std::chrono::seconds(30), d_gracefulShutdownTimeout);
        EXPECT_EQ(-2, d_priority);
    }
};
// clang-format off
const char *argvTest[] = {
    "/some/path/to/some_program.tsk",
    "--instance=dev",
    "--cas-remote=http://127.0.0.1:50011",
    "--bots-remote=http://100.70.37.178:50051",
    "--log-level=debug",
    "--buildbox-run=/opt/remoteexecution/buildbox-run-hosttools",
    "--bots-retry-limit=4",
    "--bots-retry-delay=1000",
    "--cas-retry-limit=4",
    "--cas-retry-delay=1000",
    "--ra-remote=http://127.0.0.1:8080",
    "--ra-instance=asset-instance",
    "--ra-retry-limit=5",
    "--ra-retry-delay=2000",
    "--runner-arg=--prefix-staged-dir",
    "--runner-arg=--use-localcas",
    "--runner-arg=--userchroot-bin=/bb/dbldroot/bin/userchroot",
    "--platform",
    "OSFamily=linux",
    "--platform",
    "ISA=x86-64",
    "--platform",
    "chrootRootDigest=8533ec9ba7494cc8295ccd0bfdca08457421a28b4e92c8eb18e7178fb400f5d4/930",
    "--platform",
    "chrootRootDigest=1e7088e7aca9e8713a84122218a89c8908b39b5797d32170f1afa6e474b9ade6/930",
    "--disk-usage-health-check=/tmp:90%",
    "--disk-usage-health-check=/var/cache:85%",
    "--config-file=/dbldroot/data/chroot/buildboxworker-1/opt/remoteexecution/buildboxworker.conf",
    "--max-wait-time=15",
    "--graceful-shutdown-timeout=30",
    "--preserve-update-bot-session",
    "--priority=-2",
    };
// clang-format on

class ParserTest : public ::testing::Test {
  protected:
    void test()
    {
        CmdLineSpec spec;
        buildboxcommon::CommandLine commandLine(spec.d_spec);
        EXPECT_TRUE(commandLine.parse(sizeof(argvTest) / sizeof(const char *),
                                      argvTest));
        buildboxcommon::buildboxcommonmetrics::MetricsConfigType metricsConfig;
        ParserTestWorker worker(commandLine, "", &metricsConfig);
        worker.tester();
    }
};

TEST_F(ParserTest, BasicTest) { test(); }
