// 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 <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/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;

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() : device_info_(&manager_) {}
  virtual ~DeviceInfoTest() {}

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

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

  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:
  DeviceInfo device_info_;
  MockManager manager_;
  shill::MockNetlinkManager netlink_manager_;
  base::ScopedTempDir temp_dir_;
  base::FilePath device_info_root_;
};

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);
  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);
  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);
  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();
  device->SetDeviceName(kTestDeviceName);
  EXPECT_CALL(manager_, RegisterDevice(_)).Times(1);
  RegisterDevice(device);

  // PHY info message.
  shill::NewWiphyMessage message;
  message.attributes()->CreateNl80211Attribute(NL80211_ATTR_WIPHY_NAME);
  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);
  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));
  EXPECT_CALL(manager_, RegisterDevice(device_list[0]));
  RegisterDevice(device_list[0]);
  VerifyDeviceList(device_list);
}

}  // namespace apmanager
