// 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 <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))) {}
  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_;

  DISALLOW_COPY_AND_ASSIGN(LinkMonitorObserver);
};

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, arraysize(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, arraysize(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
