// 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 "shill/link_monitor.h"

#include <base/bind.h>
#include <base/stl_util.h>
#include <gtest/gtest.h>

#include "shill/logging.h"
#include "shill/mock_active_link_monitor.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_passive_link_monitor.h"
#include "shill/net/byte_string.h"
#include "shill/net/mock_time.h"
#include "shill/test_event_dispatcher.h"

using base::Bind;
using base::Unretained;
using testing::_;
using testing::HasSubstr;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::Test;

namespace shill {

namespace {
const uint8_t kGatewayMacAddress[] = {0, 1, 2, 3, 4, 5};
}  // namespace

class LinkMonitorObserver {
 public:
  LinkMonitorObserver()
      : failure_callback_(
            Bind(&LinkMonitorObserver::OnFailureCallback, Unretained(this))),
        gateway_change_callback_(Bind(
            &LinkMonitorObserver::OnGatewayChangeCallback, Unretained(this))) {}
  LinkMonitorObserver(const LinkMonitorObserver&) = delete;
  LinkMonitorObserver& operator=(const LinkMonitorObserver&) = delete;

  virtual ~LinkMonitorObserver() = default;

  MOCK_METHOD(void, OnFailureCallback, ());
  MOCK_METHOD(void, OnGatewayChangeCallback, ());

  const LinkMonitor::FailureCallback failure_callback() const {
    return failure_callback_;
  }

  const LinkMonitor::GatewayChangeCallback gateway_change_callback() const {
    return gateway_change_callback_;
  }

 private:
  LinkMonitor::FailureCallback failure_callback_;
  LinkMonitor::GatewayChangeCallback gateway_change_callback_;
};

class LinkMonitorTest : public Test {
 public:
  LinkMonitorTest()
      : manager_(&control_, &dispatcher_, &metrics_),
        device_info_(&manager_),
        connection_(new StrictMock<MockConnection>(&device_info_)),
        active_link_monitor_(new MockActiveLinkMonitor()),
        passive_link_monitor_(new MockPassiveLinkMonitor()),
        monitor_(connection_,
                 &dispatcher_,
                 &metrics_,
                 &device_info_,
                 observer_.failure_callback(),
                 observer_.gateway_change_callback()) {}
  ~LinkMonitorTest() override = default;

  void SetUp() override {
    monitor_.active_link_monitor_.reset(active_link_monitor_);
    monitor_.passive_link_monitor_.reset(passive_link_monitor_);
    monitor_.time_ = &time_;

    time_val_.tv_sec = 0;
    time_val_.tv_usec = 0;
    EXPECT_CALL(time_, GetTimeMonotonic(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(time_val_), Return(0)));
    EXPECT_CALL(*connection_, technology())
        .WillRepeatedly(Return(Technology::kEthernet));
  }

  void AdvanceTime(int time_ms) {
    struct timeval adv_time = {static_cast<time_t>(time_ms / 1000),
                               static_cast<time_t>((time_ms % 1000) * 1000)};
    timeradd(&time_val_, &adv_time, &time_val_);
    EXPECT_CALL(time_, GetTimeMonotonic(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(time_val_), Return(0)));
  }

  void SetGatewayMacAddress(const ByteString& gateway_mac_address) {
    monitor_.gateway_mac_address_ = gateway_mac_address;
  }

  void VerifyGatewayMacAddress(const ByteString& gateway_mac_address) {
    EXPECT_TRUE(monitor_.gateway_mac_address_.Equals(gateway_mac_address));
  }

  void TriggerActiveLinkMonitorFailure(Metrics::LinkMonitorFailure failure,
                                       int broadcast_failure_count,
                                       int unicast_failure_count) {
    monitor_.OnActiveLinkMonitorFailure(failure, broadcast_failure_count,
                                        unicast_failure_count);
  }

  void TriggerActiveLinkMonitorSuccess() {
    monitor_.OnActiveLinkMonitorSuccess();
  }

  void TriggerPassiveLinkMonitorResultCallback(bool status) {
    monitor_.OnPassiveLinkMonitorResultCallback(status);
  }

 protected:
  EventDispatcherForTest dispatcher_;
  StrictMock<MockMetrics> metrics_;
  MockControl control_;
  MockManager manager_;
  NiceMock<MockDeviceInfo> device_info_;
  scoped_refptr<MockConnection> connection_;
  MockTime time_;
  struct timeval time_val_;
  MockActiveLinkMonitor* active_link_monitor_;
  MockPassiveLinkMonitor* passive_link_monitor_;
  LinkMonitorObserver observer_;
  LinkMonitor monitor_;
};

MATCHER_P(IsMacAddress, mac_address, "") {
  return mac_address.Equals(arg);
}

TEST_F(LinkMonitorTest, Start) {
  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds))
      .WillOnce(Return(false));
  EXPECT_FALSE(monitor_.Start());
  Mock::VerifyAndClearExpectations(active_link_monitor_);

  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds))
      .WillOnce(Return(true));
  EXPECT_TRUE(monitor_.Start());
  Mock::VerifyAndClearExpectations(active_link_monitor_);
}

TEST_F(LinkMonitorTest, OnAfterResume) {
  ByteString gateway_mac(kGatewayMacAddress, base::size(kGatewayMacAddress));
  const bool kGatewayUnicastArpSupport = true;
  SetGatewayMacAddress(gateway_mac);
  // Verify gateway settings persist when link monitor is restarted, and
  // active link monitor is started with fast test period.
  EXPECT_CALL(*active_link_monitor_, Stop()).Times(1);
  EXPECT_CALL(*passive_link_monitor_, Stop()).Times(1);
  EXPECT_CALL(*active_link_monitor_, gateway_supports_unicast_arp())
      .WillOnce(Return(kGatewayUnicastArpSupport));
  EXPECT_CALL(*active_link_monitor_,
              set_gateway_mac_address(IsMacAddress(gateway_mac)));
  EXPECT_CALL(*active_link_monitor_,
              set_gateway_supports_unicast_arp(kGatewayUnicastArpSupport));
  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kFastTestPeriodMilliseconds));
  monitor_.OnAfterResume();
  VerifyGatewayMacAddress(gateway_mac);
  Mock::VerifyAndClearExpectations(active_link_monitor_);
  Mock::VerifyAndClearExpectations(passive_link_monitor_);
}

TEST_F(LinkMonitorTest, OnActiveLinkMonitorFailure) {
  // Start link monitor.
  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds))
      .WillOnce(Return(true));
  EXPECT_TRUE(monitor_.Start());
  Mock::VerifyAndClearExpectations(active_link_monitor_);

  const int kBroadcastFailureCount = 5;
  const int kUnicastFailureCount = 3;
  const int kElapsedTimeMilliseconds = 5000;

  // Active monitor failed after 5 seconds.
  EXPECT_CALL(observer_, OnFailureCallback()).Times(1);
  EXPECT_CALL(metrics_,
              SendEnumToUMA(HasSubstr("LinkMonitorFailure"),
                            Metrics::kLinkMonitorFailureThresholdReached, _));
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorSecondsToFailure"),
                                  kElapsedTimeMilliseconds / 1000, _, _, _));
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("BroadcastErrorsAtFailure"),
                                  kBroadcastFailureCount, _, _, _));
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("UnicastErrorsAtFailure"),
                                  kUnicastFailureCount, _, _, _));
  AdvanceTime(kElapsedTimeMilliseconds);
  TriggerActiveLinkMonitorFailure(Metrics::kLinkMonitorFailureThresholdReached,
                                  kBroadcastFailureCount, kUnicastFailureCount);
}

TEST_F(LinkMonitorTest, OnActiveLinkMonitorSuccess) {
  ByteString gateway_mac(kGatewayMacAddress, base::size(kGatewayMacAddress));
  EXPECT_CALL(*active_link_monitor_, gateway_mac_address())
      .WillRepeatedly(ReturnRef(gateway_mac));

  // Active link monitor succeed for the first time, gateway MAC address will be
  // updated.
  EXPECT_CALL(observer_, OnGatewayChangeCallback()).Times(1);
  EXPECT_CALL(*passive_link_monitor_,
              Start(PassiveLinkMonitor::kDefaultMonitorCycles))
      .Times(1);
  TriggerActiveLinkMonitorSuccess();
  VerifyGatewayMacAddress(gateway_mac);
  Mock::VerifyAndClearExpectations(&observer_);
  Mock::VerifyAndClearExpectations(passive_link_monitor_);

  // Active link monitor succeed again, gateway MAC address not changed.
  EXPECT_CALL(observer_, OnGatewayChangeCallback()).Times(0);
  EXPECT_CALL(*passive_link_monitor_,
              Start(PassiveLinkMonitor::kDefaultMonitorCycles))
      .Times(1);
  TriggerActiveLinkMonitorSuccess();
  VerifyGatewayMacAddress(gateway_mac);
  Mock::VerifyAndClearExpectations(&observer_);
  Mock::VerifyAndClearExpectations(passive_link_monitor_);
}

TEST_F(LinkMonitorTest, OnPassiveLinkMonitorResultCallback) {
  // Active link monitor should start regardless of the result of the passive
  // link monitor.

  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
  TriggerPassiveLinkMonitorResultCallback(true);
  Mock::VerifyAndClearExpectations(active_link_monitor_);

  EXPECT_CALL(*active_link_monitor_,
              Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
  TriggerPassiveLinkMonitorResultCallback(false);
  Mock::VerifyAndClearExpectations(active_link_monitor_);
}

}  // namespace shill
