// 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/pppoe/pppoe_service.h"

#include <map>
#include <string>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <base/memory/ref_counted.h>

#include "shill/dhcp/mock_dhcp_config.h"
#include "shill/dhcp/mock_dhcp_provider.h"
#include "shill/ethernet/mock_ethernet.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_external_task.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_process_manager.h"
#include "shill/ppp_device.h"
#include "shill/ppp_device_factory.h"
#include "shill/service.h"
#include "shill/test_event_dispatcher.h"
#include "shill/testing.h"

using std::map;
using std::string;
using testing::_;
using testing::Invoke;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::StrEq;
using testing::WithoutArgs;

namespace shill {

class PPPoEServiceTest : public testing::Test {
 public:
  PPPoEServiceTest()
      : manager_(&control_interface_, &dispatcher_, &metrics_),
        ethernet_(new NiceMock<MockEthernet>(
            &manager_, "ethernet", "aabbccddeeff", 0)),
        device_info_(&manager_) {
    Service::SetNextSerialNumberForTesting(0);
    service_ =
        new PPPoEService(&manager_, ethernet_->weak_ptr_factory_.GetWeakPtr());
    manager_.set_mock_device_info(&device_info_);
    service_->process_manager_ = &process_manager_;
  }

  ~PPPoEServiceTest() override {
    Error error;
    service_->Disconnect(&error, __func__);
    dispatcher_.DispatchPendingEvents();
  }

 protected:
  void FakeConnectionSuccess() {
    EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true));
    EXPECT_CALL(process_manager_, StartProcess(_, _, _, _, _, _))
        .WillOnce(Return(0));
    Error error;
    service_->Connect(&error, "in test");
    EXPECT_TRUE(error.IsSuccess());
    service_->SetState(Service::kStateConnected);
  }

  bool IsAuthenticating() { return service_->authenticating_; }

  void OnPPPDied(pid_t pid, int exit) { service_->OnPPPDied(pid, exit); }

  int max_failure() { return service_->max_failure_; }

  const PPPDeviceRefPtr& device() { return service_->ppp_device_; }

  EventDispatcherForTest dispatcher_;
  NiceMock<MockMetrics> metrics_;
  NiceMock<MockControl> control_interface_;
  NiceMock<MockProcessManager> process_manager_;
  NiceMock<MockManager> manager_;
  scoped_refptr<NiceMock<MockEthernet>> ethernet_;
  NiceMock<MockDeviceInfo> device_info_;

  scoped_refptr<PPPoEService> service_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PPPoEServiceTest);
};

MATCHER_P(LinkNamed, name, "") {
  return arg->link_name() == name;
}

TEST_F(PPPoEServiceTest, LogName) {
  EXPECT_EQ("ppoe_0", service_->log_name());
}

TEST_F(PPPoEServiceTest, AuthenticationFailure) {
  EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true));
  FakeConnectionSuccess();
  map<string, string> empty_dict;
  service_->Notify(kPPPReasonAuthenticating, empty_dict);

  auto previous_state = service_->state();
  service_->Notify(kPPPReasonDisconnect, empty_dict);

  // First max_failure - 1 failures should not do anything; pppd will retry
  // the connection.
  for (int i = 1; i < max_failure(); ++i) {
    EXPECT_EQ(service_->state(), previous_state);
    service_->Notify(kPPPReasonDisconnect, empty_dict);
  }

  // Last auth failure should lead to the connection failing after pppd
  // terminates itself.
  OnPPPDied(0, 0);
  EXPECT_NE(service_->state(), previous_state);
  EXPECT_EQ(service_->state(), Service::kStateFailure);
  EXPECT_EQ(service_->failure(), Service::kFailurePPPAuth);
}

TEST_F(PPPoEServiceTest, DisconnectBeforeConnect) {
  EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true));
  FakeConnectionSuccess();
  map<string, string> empty_dict;
  service_->Notify(kPPPReasonAuthenticating, empty_dict);
  service_->Notify(kPPPReasonAuthenticated, empty_dict);

  constexpr int kExitCode = 10;
  service_->Notify(kPPPReasonDisconnect, empty_dict);
  OnPPPDied(0, kExitCode);
  EXPECT_EQ(service_->state(), Service::kStateFailure);
  EXPECT_EQ(service_->failure(), PPPDevice::ExitStatusToFailure(kExitCode));
}

TEST_F(PPPoEServiceTest, ConnectFailsWhenEthernetLinkDown) {
  EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(false));

  Error error;
  service_->Connect(&error, "in test");
  EXPECT_FALSE(error.IsSuccess());
}

TEST_F(PPPoEServiceTest, OnPPPConnected) {
  static const char kLinkName[] = "ppp0";
  map<string, string> params = {{kPPPInterfaceName, kLinkName}};

  EXPECT_CALL(device_info_, GetIndex(StrEq(kLinkName))).WillOnce(Return(0));
  EXPECT_CALL(device_info_, RegisterDevice(_));
#ifndef DISABLE_DHCPV6
  // Lead to the creation of a mock rather than real DHCPConfig to avoid trying
  // to create a dhcpcd process.
  NiceMock<MockDHCPProvider> dhcp_provider;
  EXPECT_CALL(dhcp_provider, CreateIPv6Config(_, _))
      .WillOnce(
          Return(new NiceMock<MockDHCPConfig>(&control_interface_, kLinkName)));
  EXPECT_CALL(manager_, IsDHCPv6EnabledForDevice(StrEq(kLinkName)))
      .WillOnce(WithoutArgs(Invoke([this, &dhcp_provider]() {
        this->device()->set_dhcp_provider(&dhcp_provider);
        return true;
      })));
#endif  // DISABLE_DHCPV6
  EXPECT_CALL(manager_, OnInnerDevicesChanged());
  service_->OnPPPConnected(params);
  Mock::VerifyAndClearExpectations(&manager_);

  // Note that crbug.com/1030324 precludes the ability of VirtualDevices to be
  // enabled(). running() suffices here.
  EXPECT_TRUE(device()->running());
  EXPECT_EQ(device()->selected_service(), service_);
  ASSERT_NE(device()->ipconfig(), nullptr);
  EXPECT_FALSE(device()->ipconfig()->properties().blackhole_ipv6);
#ifndef DISABLE_DHCPV6
  EXPECT_NE(device()->dhcpv6_config(), nullptr);
#endif  // DISABLE_DHCPV6
}

TEST_F(PPPoEServiceTest, Connect) {
  static const char kLinkName[] = "ppp0";

  EXPECT_CALL(*ethernet_, link_up()).WillRepeatedly(Return(true));
  EXPECT_CALL(device_info_, GetIndex(StrEq(kLinkName))).WillOnce(Return(0));
  EXPECT_CALL(device_info_, RegisterDevice(LinkNamed(kLinkName)));

  FakeConnectionSuccess();
  map<string, string> empty_dict;
  service_->Notify(kPPPReasonAuthenticating, empty_dict);
  service_->Notify(kPPPReasonAuthenticated, empty_dict);

  map<string, string> connect_dict = {
      {kPPPInterfaceName, kLinkName},
  };
  service_->Notify(kPPPReasonConnect, connect_dict);
  EXPECT_EQ(service_->state(), Service::kStateOnline);
}

TEST_F(PPPoEServiceTest, Disconnect) {
  FakeConnectionSuccess();

  auto weak_ptr = service_->weak_ptr_factory_.GetWeakPtr();
  MockExternalTask* pppd =
      new MockExternalTask(&control_interface_, &process_manager_, weak_ptr,
                           base::Bind(&PPPoEService::OnPPPDied, weak_ptr));
  service_->pppd_.reset(pppd);

  PPPDevice* ppp_device =
      PPPDeviceFactory::GetInstance()->CreatePPPDevice(&manager_, "ppp0", 0);
  service_->ppp_device_ = ppp_device;
  ppp_device->SelectService(service_);

  EXPECT_CALL(*pppd, OnDelete());

  Error error;
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(ppp_device->selected_service(), nullptr);
}

TEST_F(PPPoEServiceTest, DisconnectDuringAssociation) {
  FakeConnectionSuccess();

  Error error;
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());

  EXPECT_EQ(service_->state(), Service::kStateIdle);
}

}  // namespace shill
