#include <build/bazel/remote/execution/v2/remote_execution.grpc.pb.h>
#include <gmock/gmock.h>
#include <google/devtools/remoteworkers/v1test2/bots.grpc.pb.h>
#include <gtest/gtest.h>

#include <buildboxworker_actionutils.h>
#include <buildboxworker_metricnames.h>
#include <buildboxworker_worker.h>

#include <buildboxcommon_digestgenerator.h>
#include <buildboxcommon_temporaryfile.h>
#include <buildboxcommonmetrics_durationmetricvalue.h>
#include <buildboxcommonmetrics_testingutils.h>

namespace proto {
using namespace google::devtools::remoteworkers::v1test2;
using namespace build::bazel::remote::execution::v2;
} // namespace proto

using namespace testing;
using buildboxcommon::TemporaryFile;
using buildboxcommon::buildboxcommonmetrics::collectedByName;
using buildboxcommon::buildboxcommonmetrics::DurationMetricValue;
using buildboxworker::ActionUtils;

namespace {
const auto digestFunctionInitializer = []() {
    buildboxcommon::DigestGenerator::init();
    return 0;
}();
} // namespace

class DownloadActionTests : public ::testing::Test {
  protected:
    TemporaryFile testActionFile;
    proto::BotSession botSession;
    // std::string casServer = "https://foobar";
    std::shared_ptr<buildboxcommon::GrpcClient> grpcClient;
    std::shared_ptr<buildboxcommon::CASClient> casClient;
    proto::Lease *lease;
    DownloadActionTests()
        : grpcClient(std::make_shared<buildboxcommon::GrpcClient>()),
          casClient(std::make_shared<buildboxcommon::CASClient>(grpcClient)),
          lease(botSession.add_leases())
    {
        lease->set_id("42");
    }
};

TEST_F(DownloadActionTests, DownloadActionMetricsCollected)
{
    // Action:
    proto::Action action;
    action.mutable_timeout()->set_seconds(123);
    action.mutable_command_digest()->set_hash("command-hash");
    action.mutable_command_digest()->set_size_bytes(32);

    const buildboxcommon::Digest actionDigest =
        buildboxcommon::DigestGenerator::hash(action);

    // Lease containing the Action:
    proto::Lease lease;
    lease.set_id("lease-id");
    lease.mutable_payload()->PackFrom(action);

    proto::Action returnedAction;
    proto::Digest returnedActionDigest;
    std::tie(returnedAction, returnedActionDigest) =
        ActionUtils::getActionFromLease(lease, casClient);

    ASSERT_EQ(returnedActionDigest,
              buildboxcommon::DigestGenerator::hash(returnedAction));
    ASSERT_EQ(returnedActionDigest, actionDigest);

    ASSERT_TRUE(collectedByName<DurationMetricValue>(
        buildboxworker::MetricNames::TIMER_NAME_DOWNLOAD_ACTION));
}
