// Copyright 2014 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 "apmanager/device_info.h"

#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#include <map>
#include <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <shill/net/byte_string.h>
#include <shill/net/mock_netlink_manager.h>
#include "shill/net/netlink_message_matchers.h"
#include "shill/net/nl80211_attribute.h"
#include "shill/net/nl80211_message.h"
#include <shill/net/rtnl_message.h>

#include "apmanager/fake_device_adaptor.h"
#include "apmanager/mock_control.h"
#include "apmanager/mock_device.h"
#include "apmanager/mock_manager.h"

using shill::ByteString;
using shill::Nl80211Message;
using shill::RTNLMessage;
using std::map;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::Mock;
using ::testing::ReturnNew;

namespace apmanager {

namespace {

const char kTestDeviceName[] = "test-phy";
const char kTestInterface0Name[] = "test-interface0";
const char kTestInterface1Name[] = "test-interface1";
const uint32_t kTestInterface0Index = 1000;
const uint32_t kTestInterface1Index = 1001;

}  // namespace

class DeviceInfoTest : public testing::Test {
 public:
  DeviceInfoTest()
      : manager_(&control_interface_),
        device_info_(&manager_) {}
  virtual ~DeviceInfoTest() {}

  virtual void SetUp() {
    // Setup temporary directory for device info files.
    CHECK(temp_dir_.CreateUniqueTempDir());
    device_info_root_ = temp_dir_.GetPath().Append("sys/class/net");
    device_info_.device_info_root_ = device_info_root_;

    // Setup mock pointers;
    device_info_.netlink_manager_ = &netlink_manager_;

    ON_CALL(control_interface_, CreateDeviceAdaptorRaw())
      .WillByDefault(ReturnNew<FakeDeviceAdaptor>());
  }

  bool IsWifiInterface(const string& interface_name) {
    return device_info_.IsWifiInterface(interface_name);
  }

  void CreateDeviceInfoFile(const string& interface_name,
                            const string& file_name,
                            const string& contents) {
    base::FilePath info_path =
        device_info_root_.Append(interface_name).Append(file_name);
    EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
    EXPECT_TRUE(base::WriteFile(info_path, contents.c_str(), contents.size()));
  }

  void SendLinkMsg(RTNLMessage::Mode mode,
                   uint32_t interface_index,
                   const string& interface_name) {
    RTNLMessage message(RTNLMessage::kTypeLink,
                        mode,
                        0,
                        0,
                        0,
                        interface_index,
                        shill::IPAddress::kFamilyIPv4);
    message.SetAttribute(static_cast<uint16_t>(IFLA_IFNAME),
                         ByteString(interface_name, true));
    device_info_.LinkMsgHandler(message);
  }

  void VerifyInterfaceList(const vector<Device::WiFiInterface>& interfaces) {
    // Verify number of elements in the interface infos map and interface index
    // of the elements in the map.
    EXPECT_EQ(interfaces.size(), device_info_.interface_infos_.size());
    for (const auto& interface : interfaces) {
      map<uint32_t, Device::WiFiInterface>::iterator it =
          device_info_.interface_infos_.find(interface.iface_index);
      EXPECT_NE(device_info_.interface_infos_.end(), it);
      EXPECT_TRUE(interface.Equals(it->second));
    }
  }

  void VerifyDeviceList(const vector<scoped_refptr<Device>>& devices) {
    // Verify number of elements in the device map and the elements in the map.
    EXPECT_EQ(devices.size(), device_info_.devices_.size());
    for (const auto& device : devices) {
      map<string, scoped_refptr<Device>>::iterator it =
          device_info_.devices_.find(device->GetDeviceName());
      EXPECT_NE(device_info_.devices_.end(), it);
      EXPECT_EQ(device, it->second);
    }
  }
  void AddInterface(const Device::WiFiInterface& interface) {
    device_info_.interface_infos_[interface.iface_index] = interface;
  }

  void OnWiFiPhyInfoReceived(const Nl80211Message& message) {
    device_info_.OnWiFiPhyInfoReceived(message);
  }

  void OnWiFiInterfaceInfoReceived(const Nl80211Message& message) {
    device_info_.OnWiFiInterfaceInfoReceived(message);
  }

  void OnWiFiInterfacePhyInfoReceived(uint32_t interface_index,
                                      const Nl80211Message& message) {
    device_info_.OnWiFiInterfacePhyInfoReceived(interface_index, message);
  }

  void RegisterDevice(scoped_refptr<Device> device) {
    device_info_.RegisterDevice(device);
  }

 protected:
  MockControl control_interface_;
  MockManager manager_;

  shill::MockNetlinkManager netlink_manager_;
  base::ScopedTempDir temp_dir_;
  base::FilePath device_info_root_;
  DeviceInfo device_info_;
};

MATCHER_P2(IsGetInfoMessage, command, index, "") {
  if (arg->message_type() != Nl80211Message::GetMessageType()) {
    return false;
  }
  const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
  if (msg->command() != command) {
    return false;
  }
  uint32_t interface_index;
  if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
                                                     &interface_index)) {
    return false;
  }
  // kInterfaceIndex is signed, but the attribute as handed from the kernel
  // is unsigned.  We're silently casting it away with this assignment.
  uint32_t test_interface_index = index;
  return interface_index == test_interface_index;
}

MATCHER_P(IsInterface, interface, "") {
  return arg.Equals(interface);
}

MATCHER_P(IsDevice, device_name, "") {
  return arg->GetDeviceName() == device_name;
}

TEST_F(DeviceInfoTest, EnumerateDevices) {
  shill::NewWiphyMessage message;

  // No device name in the message, failed to create device.
  EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
  OnWiFiPhyInfoReceived(message);

  // Device name in the message, device should be created/register to manager.
  message.attributes()->CreateNl80211Attribute(
      NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext());
  message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME,
                                                kTestDeviceName);
  EXPECT_CALL(manager_, RegisterDevice(IsDevice(kTestDeviceName))).Times(1);
  OnWiFiPhyInfoReceived(message);
  Mock::VerifyAndClearExpectations(&manager_);

  // Receive a message for a device already created, should not create/register
  // device again.
  EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
  OnWiFiPhyInfoReceived(message);
}

TEST_F(DeviceInfoTest, IsWiFiInterface) {
  // No device info file exist, not a wifi interface.
  EXPECT_FALSE(IsWifiInterface(kTestInterface0Name));

  // Device info for an ethernet device, not a wifi interface
  CreateDeviceInfoFile(kTestInterface0Name, "uevent", "INTERFACE=eth0\n");
  EXPECT_FALSE(IsWifiInterface(kTestInterface0Name));

  // Device info for a wifi interface.
  CreateDeviceInfoFile(kTestInterface1Name, "uevent", "DEVTYPE=wlan\n");
  EXPECT_TRUE(IsWifiInterface(kTestInterface1Name));
}

TEST_F(DeviceInfoTest, InterfaceDetection) {
  vector<Device::WiFiInterface> interface_list;
  // Ignore non-wifi interface.
  SendLinkMsg(RTNLMessage::kModeAdd,
              kTestInterface0Index,
              kTestInterface0Name);
  VerifyInterfaceList(interface_list);

  // AddLink event for wifi interface.
  CreateDeviceInfoFile(kTestInterface0Name, "uevent", "DEVTYPE=wlan\n");
  EXPECT_CALL(netlink_manager_, SendNl80211Message(
      IsGetInfoMessage(NL80211_CMD_GET_INTERFACE, kTestInterface0Index),
      _, _, _)).Times(1);
  SendLinkMsg(RTNLMessage::kModeAdd,
              kTestInterface0Index,
              kTestInterface0Name);
  interface_list.push_back(Device::WiFiInterface(
      kTestInterface0Name, "", kTestInterface0Index, 0));
  VerifyInterfaceList(interface_list);
  Mock::VerifyAndClearExpectations(&netlink_manager_);

  // AddLink event for another wifi interface.
  CreateDeviceInfoFile(kTestInterface1Name, "uevent", "DEVTYPE=wlan\n");
  EXPECT_CALL(netlink_manager_, SendNl80211Message(
      IsGetInfoMessage(NL80211_CMD_GET_INTERFACE, kTestInterface1Index),
      _, _, _)).Times(1);
  SendLinkMsg(RTNLMessage::kModeAdd,
              kTestInterface1Index,
              kTestInterface1Name);
  interface_list.push_back(Device::WiFiInterface(
      kTestInterface1Name, "", kTestInterface1Index, 0));
  VerifyInterfaceList(interface_list);
  Mock::VerifyAndClearExpectations(&netlink_manager_);

  // AddLink event for an interface that's already added, no change to interface
  // list.
  EXPECT_CALL(netlink_manager_, SendNl80211Message(_, _, _, _)).Times(0);
  SendLinkMsg(RTNLMessage::kModeAdd,
              kTestInterface0Index,
              kTestInterface0Name);
  VerifyInterfaceList(interface_list);
  Mock::VerifyAndClearExpectations(&netlink_manager_);

  // Remove the first wifi interface.
  SendLinkMsg(RTNLMessage::kModeDelete,
              kTestInterface0Index,
              kTestInterface0Name);
  interface_list.clear();
  interface_list.push_back(Device::WiFiInterface(
      kTestInterface1Name, "", kTestInterface1Index, 0));
  VerifyInterfaceList(interface_list);

  // Remove the non-exist interface, no change to the list.
  SendLinkMsg(RTNLMessage::kModeDelete,
              kTestInterface0Index,
              kTestInterface0Name);
  VerifyInterfaceList(interface_list);

  // Remove the last interface, list should be empty now.
  SendLinkMsg(RTNLMessage::kModeDelete,
              kTestInterface1Index,
              kTestInterface1Name);
  interface_list.clear();
  VerifyInterfaceList(interface_list);
}

TEST_F(DeviceInfoTest, ParseWifiInterfaceInfo) {
  // Add an interface without interface type info.
  Device::WiFiInterface interface(
      kTestInterface0Name, "", kTestInterface0Index, 0);
  AddInterface(interface);
  vector<Device::WiFiInterface> interface_list;
  interface_list.push_back(interface);

  // Message contain no interface index, no change to the interface info.
  shill::NewInterfaceMessage message;
  OnWiFiInterfaceInfoReceived(message);
  VerifyInterfaceList(interface_list);

  // Message contain no interface type, no change to the interface info.
  message.attributes()->CreateNl80211Attribute(
      NL80211_ATTR_IFINDEX, shill::NetlinkMessage::MessageContext());
  message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
                                             kTestInterface0Index);
  OnWiFiInterfaceInfoReceived(message);

  // Message contain interface type, interface info should be updated with
  // the interface type, and a new Nl80211 message should be send to query for
  // the PHY info.
  EXPECT_CALL(netlink_manager_, SendNl80211Message(
      IsGetInfoMessage(NL80211_CMD_GET_WIPHY, kTestInterface0Index),
      _, _, _)).Times(1);
  message.attributes()->CreateNl80211Attribute(
      NL80211_ATTR_IFTYPE, shill::NetlinkMessage::MessageContext());
  message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
                                             NL80211_IFTYPE_AP);
  OnWiFiInterfaceInfoReceived(message);
  interface_list[0].iface_type = NL80211_IFTYPE_AP;
  VerifyInterfaceList(interface_list);
}

TEST_F(DeviceInfoTest, ParsePhyInfoForWifiInterface) {
  // Register a mock device.
  scoped_refptr<MockDevice> device = new MockDevice(&manager_);
  device->SetDeviceName(kTestDeviceName);
  EXPECT_CALL(manager_, RegisterDevice(_)).Times(1);
  RegisterDevice(device);

  // PHY info message.
  shill::NewWiphyMessage message;
  message.attributes()->CreateNl80211Attribute(
      NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext());
  message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME,
                                                kTestDeviceName);

  // Receive PHY info message for an interface that have not been detected yet.
  EXPECT_CALL(*device.get(), RegisterInterface(_)).Times(0);
  OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message);

  // Pretend interface is detected through AddLink with interface info already
  // received (interface type), and still missing PHY info for that interface.
  Device::WiFiInterface interface(
      kTestInterface0Name, "", kTestInterface0Index, NL80211_IFTYPE_AP);
  AddInterface(interface);

  // PHY info is received for a detected interface, should register that
  // interface to the corresponding Device.
  interface.device_name = kTestDeviceName;
  EXPECT_CALL(*device.get(),
              RegisterInterface(IsInterface(interface))).Times(1);
  OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message);
}

TEST_F(DeviceInfoTest, ReceivePhyInfoBeforePhyIsEnumerated) {
  // New interface is detected.
  Device::WiFiInterface interface(
      kTestInterface0Name, "", kTestInterface0Index, NL80211_IFTYPE_AP);
  AddInterface(interface);
  vector<Device::WiFiInterface> interface_list;
  interface_list.push_back(interface);

  // Received PHY info for the interface when the corresponding PHY is not
  // enumerated yet, new device should be created and register to manager.
  shill::NewWiphyMessage message;
  message.attributes()->CreateNl80211Attribute(
      NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext());
  message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME,
                                                kTestDeviceName);
  EXPECT_CALL(manager_, RegisterDevice(IsDevice(kTestDeviceName))).Times(1);
  OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message);
  interface_list[0].device_name = kTestDeviceName;
  VerifyInterfaceList(interface_list);
}

TEST_F(DeviceInfoTest, RegisterDevice) {
  vector<scoped_refptr<Device>> device_list;

  // Register a nullptr.
  RegisterDevice(nullptr);
  VerifyDeviceList(device_list);

  // Register a device.
  device_list.push_back(new Device(&manager_, kTestDeviceName, 0));
  EXPECT_CALL(manager_, RegisterDevice(device_list[0]));
  RegisterDevice(device_list[0]);
  VerifyDeviceList(device_list);
}

}  // namespace apmanager
