// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <utility>

#include <base/message_loop/message_loop.h>
#include <base/time/time.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "diagnostics/telem/async_grpc_client_adapter.h"
#include "diagnostics/telem/telem_connection.h"
#include "diagnostics/telem/telemetry_item_enum.h"

using ::testing::_;
using ::testing::Invoke;
using ::testing::StrictMock;
using ::testing::WithArg;

namespace diagnostics {

namespace {

using ProcDataCallback = base::Callback<void(
    std::unique_ptr<grpc_api::GetProcDataResponse> response)>;
using SysfsDataCallback = base::Callback<void(
    std::unique_ptr<grpc_api::GetSysfsDataResponse> response)>;

constexpr char kFakeMeminfoFileContents[] =
    "MemTotal:      3906320 kB\nMemFree:      873180 kB\n";
constexpr char kFakeBadMeminfoFileContents[] =
    "MemTotal:      3906320\nMemfree:      873180 kB\n";
constexpr int kFakeMemTotalMebibytes = 3814;
constexpr int kFakeMemFreeMebibytes = 852;
constexpr char kFakeLoadavgFileContents[] = "0.82 0.61 0.52 2/370 30707\n";
constexpr char kFakeBadLoadavgFileContents[] = "0.82 0.61 0.52 2 370 30707\n";
constexpr int kFakeNumRunnableEntities = 2;
constexpr int kFakeNumExistingEntities = 370;
constexpr char kFakeStatFileContents[] =
    "cpu  0 0 0 165432156432413546\ncpu0 0 0 0 653435243543\ncpu1 0 0 0 "
    "235435413\nctxt 5345634354";
constexpr char kFakeBadStatFileContents[] =
    "cpu  0 0 165432156432413546\npu0 0 0 0 653435243543\ncpu1 0 0 0 "
    "235435413\nctxt 5345634354";
constexpr char kFakeTotalCPUIdleTime[] = "165432156432413546";
char const* kFakePerCPUIdleTimes[] = {"653435243543", "235435413"};

class MockAsyncGrpcClientAdapter : public AsyncGrpcClientAdapter {
 public:
  void Connect(const std::string& target_uri) override {}

  MOCK_CONST_METHOD0(IsConnected, bool());
  MOCK_METHOD1(Shutdown, void(const base::Closure& on_shutdown));
  MOCK_METHOD2(GetProcData,
               void(const grpc_api::GetProcDataRequest& request,
                    ProcDataCallback callback));
  MOCK_METHOD2(GetSysfsData,
               void(const grpc_api::GetSysfsDataRequest& request,
                    SysfsDataCallback callback));
};

}  // namespace

class TelemConnectionTest : public ::testing::Test {
 protected:
  TelemConnectionTest() {
    EXPECT_CALL(mock_adapter_, Shutdown(_))
        .WillOnce(Invoke(
            [](const base::Closure& on_shutdown) { on_shutdown.Run(); }));
  }

  void SetConnection(std::unique_ptr<TelemConnection> connection) {
    connection_ = std::move(connection);
  }

  // Sets the MockAsyncGrpcClientAdapter to run the next callback with
  // a null pointer as its response.
  void SetNullptrProcDataResponse() {
    EXPECT_CALL(mock_adapter_, GetProcData(_, _))
        .WillOnce(WithArg<1>(
            Invoke([](ProcDataCallback callback) { callback.Run(nullptr); })));
  }

  // Sets the MockAsyncGrpcClientAdapter to run the next callback with a
  // fake file dump as its ProcDataResponse.
  void SetProcDataResponse(const std::string& file_contents) {
    std::unique_ptr<grpc_api::GetProcDataResponse> response =
        std::make_unique<grpc_api::GetProcDataResponse>();
    // response->mutable_file_dump()->Add()
    EXPECT_CALL(mock_adapter_, GetProcData(_, _))
        .WillRepeatedly(
            Invoke([file_contents](::testing::Unused,
                                   ProcDataCallback callback) mutable {
              std::unique_ptr<grpc_api::GetProcDataResponse> reply =
                  std::make_unique<grpc_api::GetProcDataResponse>();
              grpc_api::FileDump fake_file_dump;
              fake_file_dump.set_contents(file_contents);
              reply->mutable_file_dump()->Add()->Swap(&fake_file_dump);
              callback.Run(std::move(reply));
            }));
  }

  // Checks whether the response matches the expected response from a
  // GetItem(item) command. |item| must be expected as an integer.
  void CheckIntegerItemResponse(
      const base::Optional<base::Value>& actual_response,
      TelemetryItemEnum item) {
    int val;

    // Make sure that a value was returned, and that value has an integer
    // representation.
    ASSERT_TRUE(actual_response);
    ASSERT_TRUE(actual_response.value().GetAsInteger(&val));
    switch (item) {
      case TelemetryItemEnum::kMemTotalMebibytes:
        EXPECT_EQ(val, kFakeMemTotalMebibytes);
        break;
      case TelemetryItemEnum::kMemFreeMebibytes:
        EXPECT_EQ(val, kFakeMemFreeMebibytes);
        break;
      case TelemetryItemEnum::kNumRunnableEntities:
        EXPECT_EQ(val, kFakeNumRunnableEntities);
        break;
      case TelemetryItemEnum::kNumExistingEntities:
        EXPECT_EQ(val, kFakeNumExistingEntities);
        break;
      default:
        // We should never get here, because all items currently tested
        // which have integer representations are enumerated above. However,
        // we need this default case, because some TelemetryItemEnums
        // cannot be represented as integers and are not checked here.
        break;
    }
  }

  // Checks whether the response matches the expected response from a
  // GetItem(item) command. |item| must be expected as a string.
  void CheckStringItemResponse(
      const base::Optional<base::Value>& actual_response,
      TelemetryItemEnum item) {
    std::string val;

    // Make sure that a value was returned, and that value has a string
    // representation.
    ASSERT_TRUE(actual_response);
    ASSERT_TRUE(actual_response.value().GetAsString(&val));
    switch (item) {
      case TelemetryItemEnum::kTotalIdleTimeUserHz:
        EXPECT_EQ(val, kFakeTotalCPUIdleTime);
        break;
      default:
        // We should never get here, because all items currently tested
        // which have string representations are enumerated above. However,
        // we need this default case, because some TelemetryItemEnums
        // cannot be represented as strings and are not checked here.
        break;
    }
  }

  // Checks whether the response matches the expected response from a
  // GetItem(item) command. |item| must be expected as a list.
  void CheckListItemResponse(const base::Optional<base::Value>& actual_response,
                             TelemetryItemEnum item) {
    const base::ListValue* list_val;
    std::string val;

    // Make sure that a value was returned, and that value has a list
    // representation.
    ASSERT_TRUE(actual_response);
    ASSERT_TRUE(actual_response.value().GetAsList(&list_val));
    switch (item) {
      case TelemetryItemEnum::kIdleTimePerCPUUserHz: {
        for (int i = 0; i < list_val->GetSize(); i++) {
          ASSERT_TRUE(list_val->GetString(i, &val));
          EXPECT_EQ(val, kFakePerCPUIdleTimes[i]);
        }
        break;
      }
      default: {
        // We should never get here, because all items currently tested
        // which have list representations are enumerated above. However,
        // we need this default case, because some TelemetryItemEnums
        // cannot be represented as lists and are not checked here.
        break;
      }
    }
  }

  // Checks whether the response matches the expected response
  // from a GetGroup(TelemetryGroupEnum::kDisk) command.
  void CheckDiskGroupResponse(
      const std::vector<
          std::pair<TelemetryItemEnum, const base::Optional<base::Value>>>&
          actual_response) {
    // Indices where we expect MemTotal and MemFree to occur in the response.
    constexpr int kMemTotalIndex = 0;
    constexpr int kMemFreeIndex = 1;
    // Number of items in the kDisk group.
    constexpr int kNumDiskItems = 2;

    int val;

    EXPECT_EQ(actual_response.size(), kNumDiskItems);
    ASSERT_EQ(actual_response[kMemTotalIndex].first,
              TelemetryItemEnum::kMemTotalMebibytes);
    ASSERT_TRUE(actual_response[kMemTotalIndex].second);
    ASSERT_TRUE(
        actual_response[kMemTotalIndex].second.value().GetAsInteger(&val));
    EXPECT_EQ(val, kFakeMemTotalMebibytes);
    EXPECT_EQ(actual_response[kMemFreeIndex].first,
              TelemetryItemEnum::kMemFreeMebibytes);
    ASSERT_TRUE(actual_response[kMemFreeIndex].second);
    ASSERT_TRUE(
        actual_response[kMemFreeIndex].second.value().GetAsInteger(&val));
    EXPECT_EQ(val, kFakeMemFreeMebibytes);
  }

  TelemConnection* connection() { return connection_.get(); }

 private:
  base::MessageLoopForIO message_loop_;
  StrictMock<MockAsyncGrpcClientAdapter> mock_adapter_;
  std::unique_ptr<TelemConnection> connection_ =
      std::make_unique<TelemConnection>(&mock_adapter_);

  DISALLOW_COPY_AND_ASSIGN(TelemConnectionTest);
};

// Test that we catch an error response.
TEST_F(TelemConnectionTest, NullptrResponse) {
  SetNullptrProcDataResponse();

  EXPECT_EQ(connection()->GetItem(TelemetryItemEnum::kMemTotalMebibytes,
                                  base::TimeDelta()),
            base::nullopt);
}

// Test that we can retrieve kMemTotalMebibytes.
TEST_F(TelemConnectionTest, GetMemTotal) {
  SetProcDataResponse(kFakeMeminfoFileContents);

  auto mem_total = connection()->GetItem(TelemetryItemEnum::kMemTotalMebibytes,
                                         base::TimeDelta());
  CheckIntegerItemResponse(mem_total, TelemetryItemEnum::kMemTotalMebibytes);
}

// Test that we can retrieve kMemFreeMebibytes.
TEST_F(TelemConnectionTest, GetMemFree) {
  SetProcDataResponse(kFakeMeminfoFileContents);

  auto mem_free = connection()->GetItem(TelemetryItemEnum::kMemFreeMebibytes,
                                        base::TimeDelta());
  CheckIntegerItemResponse(mem_free, TelemetryItemEnum::kMemFreeMebibytes);
}

// Test that an incorrectly formatted /proc/meminfo will fail to parse.
TEST_F(TelemConnectionTest, GetBadMeminfo) {
  SetProcDataResponse(kFakeBadMeminfoFileContents);

  auto mem_total = connection()->GetItem(TelemetryItemEnum::kMemTotalMebibytes,
                                         base::TimeDelta());
  EXPECT_EQ(mem_total, base::nullopt);
  auto mem_free = connection()->GetItem(TelemetryItemEnum::kMemFreeMebibytes,
                                        base::TimeDelta());
  EXPECT_EQ(mem_free, base::nullopt);
}

// Test that we can retrieve kNumRunnableEntities.
TEST_F(TelemConnectionTest, GetRunnableEntities) {
  SetProcDataResponse(kFakeLoadavgFileContents);

  auto runnable_entities = connection()->GetItem(
      TelemetryItemEnum::kNumRunnableEntities, base::TimeDelta());
  CheckIntegerItemResponse(runnable_entities,
                           TelemetryItemEnum::kNumRunnableEntities);
}

// Test that we can retrieve kNumExistingEntities.
TEST_F(TelemConnectionTest, GetExistingEntities) {
  SetProcDataResponse(kFakeLoadavgFileContents);

  auto existing_entities = connection()->GetItem(
      TelemetryItemEnum::kNumExistingEntities, base::TimeDelta());
  CheckIntegerItemResponse(existing_entities,
                           TelemetryItemEnum::kNumExistingEntities);
}

// Test that an incorrectly formatted /proc/loadavg will fail to parse.
TEST_F(TelemConnectionTest, GetBadLoadAvg) {
  SetProcDataResponse(kFakeBadLoadavgFileContents);

  auto runnable_entities = connection()->GetItem(
      TelemetryItemEnum::kNumRunnableEntities, base::TimeDelta());
  EXPECT_EQ(runnable_entities, base::nullopt);
  auto existing_entities = connection()->GetItem(
      TelemetryItemEnum::kNumExistingEntities, base::TimeDelta());
  EXPECT_EQ(existing_entities, base::nullopt);
}

// Test that we can retrieve kTotalIdleTime.
TEST_F(TelemConnectionTest, GetTotalIdleTime) {
  SetProcDataResponse(kFakeStatFileContents);

  auto idle_time = connection()->GetItem(
      TelemetryItemEnum::kTotalIdleTimeUserHz, base::TimeDelta());
  CheckStringItemResponse(idle_time, TelemetryItemEnum::kTotalIdleTimeUserHz);
}

// Test that we can retrieve kIdleTimePerCPU.
TEST_F(TelemConnectionTest, GetIdleTimePerCPU) {
  SetProcDataResponse(kFakeStatFileContents);

  auto idle_times = connection()->GetItem(
      TelemetryItemEnum::kIdleTimePerCPUUserHz, base::TimeDelta());
  CheckListItemResponse(idle_times, TelemetryItemEnum::kIdleTimePerCPUUserHz);
}

// Test that an incorrectly formatted /proc/stat will fail to parse.
TEST_F(TelemConnectionTest, GetBadStat) {
  SetProcDataResponse(kFakeBadStatFileContents);

  auto total_idle_time = connection()->GetItem(
      TelemetryItemEnum::kTotalIdleTimeUserHz, base::TimeDelta());
  EXPECT_EQ(total_idle_time, base::nullopt);
  auto idle_times_per_cpu = connection()->GetItem(
      TelemetryItemEnum::kIdleTimePerCPUUserHz, base::TimeDelta());
  EXPECT_EQ(idle_times_per_cpu, base::nullopt);
}

// Test that we can retrieve a group of telemetry items.
TEST_F(TelemConnectionTest, GetDiskGroup) {
  SetProcDataResponse(kFakeMeminfoFileContents);

  auto disk_group =
      connection()->GetGroup(TelemetryGroupEnum::kDisk, base::TimeDelta());
  CheckDiskGroupResponse(disk_group);
}

}  // namespace diagnostics
