// Copyright (c) 2011 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 <time.h>

#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <fcntl.h>
#include <string>

#include <base/callback_old.h>
#include <base/hash_tables.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <base/stringprintf.h>

#include "shill/control_interface.h"
#include "shill/device.h"
#include "shill/device_info.h"
#include "shill/device_stub.h"
#include "shill/ethernet.h"
#include "shill/manager.h"
#include "shill/rtnl_handler.h"
#include "shill/rtnl_listener.h"
#include "shill/service.h"
#include "shill/wifi.h"

using std::string;

namespace shill {

// static
const char *DeviceInfo::kInterfaceUevent= "/sys/class/net/%s/uevent";
// static
const char *DeviceInfo::kInterfaceDriver= "/sys/class/net/%s/device/driver";
// static
const char *DeviceInfo::kModemDrivers[] = {
    "gobi",
    "QCUSBNet2k",
    "GobiNet",
    NULL
};


DeviceInfo::DeviceInfo(ControlInterface *control_interface,
                       EventDispatcher *dispatcher,
                       Manager *manager)
    : control_interface_(control_interface),
      dispatcher_(dispatcher),
      manager_(manager),
      link_callback_(NewCallback(this, &DeviceInfo::LinkMsgHandler)),
      link_listener_(NULL) {
}

DeviceInfo::~DeviceInfo() {}

void DeviceInfo::Start() {
  link_listener_.reset(
      new RTNLListener(RTNLHandler::kRequestLink, link_callback_.get()));
  RTNLHandler::GetInstance()->RequestDump(RTNLHandler::kRequestLink);
}

void DeviceInfo::Stop() {
  link_listener_.reset(NULL);
}

Device::Technology DeviceInfo::GetDeviceTechnology(const char *interface_name) {
  char contents[1024];
  int length;
  int fd;
  string uevent_file = StringPrintf(kInterfaceUevent, interface_name);
  string driver_file = StringPrintf(kInterfaceDriver, interface_name);
  const char *wifi_type;
  const char *driver_name;
  int modem_idx;

  fd = open(uevent_file.c_str(), O_RDONLY);
  if (fd < 0)
    return Device::kUnknown;

  length = read(fd, contents, sizeof(contents) - 1);
  if (length < 0)
    return Device::kUnknown;

  /*
   * If the "uevent" file contains the string "DEVTYPE=wlan\n" at the
   * start of the file or after a newline, we can safely assume this
   * is a wifi device.
   */
  contents[length] = '\0';
  wifi_type = strstr(contents, "DEVTYPE=wlan\n");
  if (wifi_type != NULL && (wifi_type == contents || wifi_type[-1] == '\n'))
    return Device::kWifi;

  length = readlink(driver_file.c_str(), contents, sizeof(contents)-1);
  if (length < 0)
    return Device::kUnknown;

  contents[length] = '\0';
  driver_name = strrchr(contents, '/');
  if (driver_name != NULL) {
    driver_name++;
    // See if driver for this interface is in a list of known modem driver names
    for (modem_idx = 0; kModemDrivers[modem_idx] != NULL; modem_idx++)
      if (strcmp(driver_name, kModemDrivers[modem_idx]) == 0)
        return Device::kCellular;
  }

  return Device::kEthernet;
}

void DeviceInfo::AddLinkMsgHandler(struct nlmsghdr *hdr) {
  struct ifinfomsg *msg = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(hdr));
  base::hash_map<int, scoped_refptr<Device> >::iterator ndev =
      devices_.find(msg->ifi_index);
  int bytes = IFLA_PAYLOAD(hdr);
  int dev_index = msg->ifi_index;
  struct rtattr *rta;
  int rta_bytes;
  char *link_name = NULL;
  scoped_refptr<Device> device;
  Device::Technology technology;
  bool is_stub = false;

  VLOG(2) << __func__;

  if (ndev == devices_.end()) {
    rta_bytes = IFLA_PAYLOAD(hdr);
    for (rta = IFLA_RTA(msg); RTA_OK(rta, rta_bytes);
         rta = RTA_NEXT(rta, rta_bytes)) {
      if (rta->rta_type == IFLA_IFNAME) {
        link_name = reinterpret_cast<char *>(RTA_DATA(rta));
        break;
      } else {
        VLOG(2) << " RTA type " << rta->rta_type;
      }
    }

    VLOG(2) << "add link index "  << dev_index << " name " << link_name;

    if (link_name != NULL)
      technology = GetDeviceTechnology(link_name);

    switch (technology) {
    case Device::kEthernet:
      device = new Ethernet(control_interface_, dispatcher_, manager_,
                            link_name, dev_index);
      break;
    case Device::kWifi:
      device = new WiFi(control_interface_, dispatcher_, manager_,
                        link_name, dev_index);
      break;
    default:
      device = new DeviceStub(control_interface_, dispatcher_, manager_,
                              link_name, dev_index, technology);
      is_stub = true;
    }

    devices_[dev_index] = device;

    if (!is_stub)
      manager_->RegisterDevice(device);
  } else {
    device = ndev->second;
  }

  device->LinkEvent(msg->ifi_flags, msg->ifi_change);
}

void DeviceInfo::DelLinkMsgHandler(struct nlmsghdr *hdr) {
  struct ifinfomsg *msg = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(hdr));
  base::hash_map<int, scoped_refptr<Device> >::iterator ndev =
      devices_.find(msg->ifi_index);
  int dev_index = msg->ifi_index;
  scoped_refptr<Device> device;

  if (ndev != devices_.end()) {
    device = ndev->second;
    manager_->DeregisterDevice(device.get());
    devices_.erase(ndev);
  }
}

void DeviceInfo::LinkMsgHandler(struct nlmsghdr *hdr) {
  if (hdr->nlmsg_type == RTM_NEWLINK) {
    AddLinkMsgHandler(hdr);
  } else if (hdr->nlmsg_type == RTM_DELLINK) {
    DelLinkMsgHandler(hdr);
  }
}

}  // namespace shill
