// Copyright 2020 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 <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/run_loop.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/public/cpp/bindings/binding.h>

#include "diagnostics/wilco_dtc_supportd/probe_service_impl.h"
#include "mojo/cros_healthd.mojom.h"
#include "mojo/cros_healthd_probe.mojom.h"

using testing::_;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;

namespace diagnostics {
namespace mojo_ipc = ::chromeos::cros_healthd::mojom;

namespace {

class MockCallback {
 public:
  MOCK_METHOD(void, OnTelemetryInfo, (mojo_ipc::TelemetryInfoPtr));
};

class MockProbeService : public mojo_ipc::CrosHealthdProbeService {
 public:
  MOCK_METHOD(void,
              ProbeProcessInfo,
              (uint32_t, ProbeProcessInfoCallback),
              (override));
  MOCK_METHOD(void,
              ProbeTelemetryInfo,
              (const std::vector<mojo_ipc::ProbeCategoryEnum>&,
               ProbeTelemetryInfoCallback),
              (override));
};

class MockProbeServiceDelegate : public ProbeService::Delegate {
 public:
  MOCK_METHOD(bool,
              BindCrosHealthdProbeService,
              (mojo_ipc::CrosHealthdProbeServiceRequest),
              (override));
};

}  // namespace

// Tests for the ProbeServiceImpl class.
class ProbeServiceImplTest : public testing::Test {
 public:
  ProbeServiceImplTest() = default;

  MockCallback* mock_callback() { return &mock_callback_; }

  MockProbeService* mock_probe_service() { return &mock_probe_service_; }

  mojo::Binding<mojo_ipc::CrosHealthdProbeService>* service_binding() {
    return &service_binding_;
  }

  MockProbeServiceDelegate* mock_delegate() { return &mock_delegate_; }

  ProbeService* service() { return &service_; }

 private:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};

  StrictMock<MockCallback> mock_callback_;

  StrictMock<MockProbeService> mock_probe_service_;
  mojo::Binding<mojo_ipc::CrosHealthdProbeService> service_binding_{
      &mock_probe_service_ /* impl */};

  StrictMock<MockProbeServiceDelegate> mock_delegate_;

  ProbeServiceImpl service_{&mock_delegate_};
};

TEST_F(ProbeServiceImplTest, ProbeServiceNotAvailable) {
  EXPECT_CALL(*mock_callback(), OnTelemetryInfo(_))
      .WillOnce(
          Invoke([](mojo_ipc::TelemetryInfoPtr ptr) { EXPECT_FALSE(ptr); }));
  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_));

  service()->ProbeTelemetryInfo(
      {}, base::BindOnce(&MockCallback::OnTelemetryInfo,
                         base::Unretained(mock_callback())));
}

TEST_F(ProbeServiceImplTest, ProbeServiceNotResponsive) {
  EXPECT_CALL(*mock_callback(), OnTelemetryInfo(_))
      .WillOnce(
          Invoke([](mojo_ipc::TelemetryInfoPtr ptr) { EXPECT_FALSE(ptr); }));
  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
      .WillOnce(Return(true));

  service()->ProbeTelemetryInfo(
      {}, base::BindOnce(&MockCallback::OnTelemetryInfo,
                         base::Unretained(mock_callback())));
}

TEST_F(ProbeServiceImplTest, DroppedConnection) {
  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
      .WillOnce(Return(true));

  base::RunLoop run_loop;
  service()->ProbeTelemetryInfo(
      {}, base::BindOnce(
              [](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
                EXPECT_FALSE(ptr);
                callback.Run();
              },
              run_loop.QuitClosure()));
  run_loop.Run();
}

TEST_F(ProbeServiceImplTest, RecoverAfterDroppedConnection) {
  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
      .WillOnce(Return(true));

  base::RunLoop run_loop1;
  service()->ProbeTelemetryInfo(
      {}, base::BindOnce(
              [](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
                EXPECT_FALSE(ptr);
                callback.Run();
              },
              run_loop1.QuitClosure()));
  run_loop1.Run();

  EXPECT_CALL(*mock_probe_service(), ProbeTelemetryInfo(_, _))
      .WillOnce(Invoke(
          [](const std::vector<mojo_ipc::ProbeCategoryEnum>& categories,
             mojo_ipc::CrosHealthdProbeService::ProbeTelemetryInfoCallback
                 callback) {
            mojo_ipc::TelemetryInfo telemetry_info;
            std::move(callback).Run(telemetry_info.Clone());
          }));

  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
      .WillOnce(
          Invoke([service_binding = service_binding()](
                     mojo_ipc::CrosHealthdProbeServiceRequest request) -> bool {
            service_binding->Bind(std::move(request));
            return true;
          }));

  base::RunLoop run_loop2;
  service()->ProbeTelemetryInfo(
      {}, base::BindOnce(
              [](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
                EXPECT_TRUE(ptr);
                callback.Run();
              },
              run_loop2.QuitClosure()));
  run_loop2.Run();
}

TEST_F(ProbeServiceImplTest, ProbeTelemetryInfo) {
  const std::vector<mojo_ipc::ProbeCategoryEnum> kCategories{
      mojo_ipc::ProbeCategoryEnum::kBattery};

  EXPECT_CALL(*mock_probe_service(), ProbeTelemetryInfo(kCategories, _))
      .WillOnce(Invoke(
          [](const std::vector<mojo_ipc::ProbeCategoryEnum>& categories,
             mojo_ipc::CrosHealthdProbeService::ProbeTelemetryInfoCallback
                 callback) {
            mojo_ipc::TelemetryInfo telemetry_info;
            telemetry_info.battery_result =
                mojo_ipc::BatteryResult::NewBatteryInfo(
                    mojo_ipc::BatteryInfoPtr());

            std::move(callback).Run(telemetry_info.Clone());
          }));

  EXPECT_CALL(*mock_delegate(), BindCrosHealthdProbeService(_))
      .WillOnce(
          Invoke([service_binding = service_binding()](
                     mojo_ipc::CrosHealthdProbeServiceRequest request) -> bool {
            service_binding->Bind(std::move(request));
            return true;
          }));

  base::RunLoop run_loop;
  service()->ProbeTelemetryInfo(
      kCategories,
      base::BindOnce(
          [](base::Closure callback, mojo_ipc::TelemetryInfoPtr ptr) {
            ASSERT_TRUE(ptr);
            EXPECT_TRUE(ptr->battery_result->is_battery_info());
            callback.Run();
          },
          run_loop.QuitClosure()));
  run_loop.Run();
}

}  // namespace diagnostics
