/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2018 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * @author Davide Pesavento <davide.pesavento@lip6.fr>
 */

#include "network-monitor-impl-netlink.hpp"
#include "linux-if-constants.hpp"
#include "netlink-message.hpp"
#include "../network-address.hpp"
#include "../network-interface.hpp"
#include "../../util/logger.hpp"

#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <net/if_arp.h>

NDN_LOG_INIT(ndn.NetworkMonitor);

namespace ndn {
namespace net {

NetworkMonitorImplNetlink::NetworkMonitorImplNetlink(boost::asio::io_service& io)
  : m_rtnlSocket(io)
  , m_isEnumeratingLinks(false)
  , m_isEnumeratingAddresses(false)
{
  m_rtnlSocket.open();
  for (auto group : {RTNLGRP_LINK,
                     RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV4_ROUTE,
                     RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_ROUTE}) {
    m_rtnlSocket.joinGroup(group);
  }

  m_rtnlSocket.startAsyncReceive([this] (const auto& msg) { this->parseRtnlMessage(msg); });

  NDN_LOG_TRACE("enumerating links");
  m_rtnlSocket.sendDumpRequest(RTM_GETLINK);
  m_isEnumeratingLinks = true;
}

shared_ptr<const NetworkInterface>
NetworkMonitorImplNetlink::getNetworkInterface(const std::string& ifname) const
{
  for (const auto& e : m_interfaces) {
    if (e.second->getName() == ifname)
      return e.second;
  }
  return nullptr;
}

std::vector<shared_ptr<const NetworkInterface>>
NetworkMonitorImplNetlink::listNetworkInterfaces() const
{
  std::vector<shared_ptr<const NetworkInterface>> v;
  v.reserve(m_interfaces.size());

  for (const auto& e : m_interfaces) {
    v.push_back(e.second);
  }
  return v;
}

bool
NetworkMonitorImplNetlink::isEnumerating() const
{
  return m_isEnumeratingLinks || m_isEnumeratingAddresses;
}

void
NetworkMonitorImplNetlink::parseRtnlMessage(const NetlinkMessage& nlmsg)
{
  switch (nlmsg->nlmsg_type) {
  case RTM_NEWLINK:
  case RTM_DELLINK:
    parseLinkMessage(nlmsg);
    if (!isEnumerating())
      this->emitSignal(onNetworkStateChanged); // backward compat
    break;

  case RTM_NEWADDR:
  case RTM_DELADDR:
    parseAddressMessage(nlmsg);
    if (!isEnumerating())
      this->emitSignal(onNetworkStateChanged); // backward compat
    break;

  case RTM_NEWROUTE:
  case RTM_DELROUTE:
    parseRouteMessage(nlmsg);
    if (!isEnumerating())
      this->emitSignal(onNetworkStateChanged); // backward compat
    break;

  case NLMSG_DONE:
    if (m_isEnumeratingLinks) {
      // links enumeration complete, now request all the addresses
      m_isEnumeratingLinks = false;
      NDN_LOG_TRACE("enumerating addresses");
      m_rtnlSocket.sendDumpRequest(RTM_GETADDR);
      m_isEnumeratingAddresses = true;
    }
    else if (m_isEnumeratingAddresses) {
      // links and addresses enumeration complete
      m_isEnumeratingAddresses = false;
      // TODO: enumerate routes
      NDN_LOG_DEBUG("enumeration complete");
      this->emitSignal(onEnumerationCompleted);
    }
    break;

  case NLMSG_ERROR:
    parseErrorMessage(nlmsg);
    break;
  }
}

static InterfaceType
ifiTypeToInterfaceType(uint16_t type)
{
  switch (type) {
    case ARPHRD_ETHER:
      return InterfaceType::ETHERNET;
    case ARPHRD_LOOPBACK:
      return InterfaceType::LOOPBACK;
    default:
      return InterfaceType::UNKNOWN;
  }
}

static AddressFamily
ifaFamilyToAddressFamily(uint8_t family)
{
  switch (family) {
    case AF_INET:
      return AddressFamily::V4;
    case AF_INET6:
      return AddressFamily::V6;
    default:
      return AddressFamily::UNSPECIFIED;
  }
}

static AddressScope
ifaScopeToAddressScope(uint8_t scope)
{
  switch (scope) {
    case RT_SCOPE_NOWHERE:
      return AddressScope::NOWHERE;
    case RT_SCOPE_HOST:
      return AddressScope::HOST;
    case RT_SCOPE_LINK:
      return AddressScope::LINK;
    default:
      return AddressScope::GLOBAL;
  }
}

static void
updateInterfaceState(NetworkInterface& interface, uint8_t operState)
{
  if (operState == linux_if::OPER_STATE_UP) {
    interface.setState(InterfaceState::RUNNING);
  }
  else if (operState == linux_if::OPER_STATE_DORMANT) {
    interface.setState(InterfaceState::DORMANT);
  }
  else {
    // fallback to flags
    auto flags = interface.getFlags();
    if ((flags & linux_if::FLAG_LOWER_UP) && !(flags & linux_if::FLAG_DORMANT))
      interface.setState(InterfaceState::RUNNING);
    else if (flags & IFF_UP)
      interface.setState(InterfaceState::NO_CARRIER);
    else
      interface.setState(InterfaceState::DOWN);
  }
}

void
NetworkMonitorImplNetlink::parseLinkMessage(const NetlinkMessage& nlmsg)
{
  const ifinfomsg* ifi = nlmsg.getPayload<ifinfomsg>();
  if (ifi == nullptr) {
    NDN_LOG_WARN("malformed ifinfomsg");
    return;
  }

  if (ifiTypeToInterfaceType(ifi->ifi_type) == InterfaceType::UNKNOWN) {
    NDN_LOG_DEBUG("unhandled interface type " << ifi->ifi_type);
    return;
  }

  shared_ptr<NetworkInterface> interface;
  auto it = m_interfaces.find(ifi->ifi_index);
  if (it != m_interfaces.end()) {
    interface = it->second;
    BOOST_ASSERT(interface != nullptr);
    BOOST_ASSERT(interface->getIndex() == ifi->ifi_index);
  }

  if (nlmsg->nlmsg_type == RTM_DELLINK) {
    if (interface != nullptr) {
      NDN_LOG_DEBUG("removing interface " << interface->getName());
      m_interfaces.erase(it);
      this->emitSignal(onInterfaceRemoved, interface);
    }
    return;
  }

  if (interface == nullptr) {
    interface = makeNetworkInterface();
    interface->setIndex(ifi->ifi_index);
  }
  interface->setType(ifiTypeToInterfaceType(ifi->ifi_type));
  interface->setFlags(ifi->ifi_flags);

  auto attrs = nlmsg.getAttributes<rtattr>(ifi);
  NDN_LOG_TRACE("message contains " << attrs.size() << " attributes");

  auto address = attrs.getAttributeByType<ethernet::Address>(IFLA_ADDRESS);
  if (address)
    interface->setEthernetAddress(*address);

  auto broadcast = attrs.getAttributeByType<ethernet::Address>(IFLA_BROADCAST);
  if (broadcast)
    interface->setEthernetBroadcastAddress(*broadcast);

  auto name = attrs.getAttributeByType<std::string>(IFLA_IFNAME);
  if (name)
    interface->setName(*name);

  auto mtu = attrs.getAttributeByType<uint32_t>(IFLA_MTU);
  if (mtu)
    interface->setMtu(*mtu);

  auto state = attrs.getAttributeByType<uint8_t>(IFLA_OPERSTATE);
  updateInterfaceState(*interface, state ? *state : linux_if::OPER_STATE_UNKNOWN);

  if (it == m_interfaces.end()) {
    NDN_LOG_DEBUG("adding interface " << interface->getName());
    m_interfaces[interface->getIndex()] = interface;
    this->emitSignal(onInterfaceAdded, interface);
  }
}

void
NetworkMonitorImplNetlink::parseAddressMessage(const NetlinkMessage& nlmsg)
{
  const ifaddrmsg* ifa = nlmsg.getPayload<ifaddrmsg>();
  if (ifa == nullptr) {
    NDN_LOG_WARN("malformed ifaddrmsg");
    return;
  }

  auto it = m_interfaces.find(ifa->ifa_index);
  if (it == m_interfaces.end()) {
    // unknown interface, ignore message
    NDN_LOG_TRACE("unknown interface index " << ifa->ifa_index);
    return;
  }
  auto interface = it->second;
  BOOST_ASSERT(interface != nullptr);

  auto attrs = nlmsg.getAttributes<rtattr>(ifa);
  NDN_LOG_TRACE("message contains " << attrs.size() << " attributes");

  namespace ip = boost::asio::ip;
  ip::address ipAddr, broadcastAddr;
  if (ifa->ifa_family == AF_INET) {
    auto v4 = attrs.getAttributeByType<ip::address_v4>(IFA_LOCAL);
    if (v4)
      ipAddr = *v4;

    v4 = attrs.getAttributeByType<ip::address_v4>(IFA_BROADCAST);
    if (v4)
      broadcastAddr = *v4;
  }
  else if (ifa->ifa_family == AF_INET6) {
    auto v6 = attrs.getAttributeByType<ip::address_v6>(IFA_ADDRESS);
    if (v6) {
      if (v6->is_link_local())
        v6->scope_id(ifa->ifa_index);

      ipAddr = *v6;
    }
  }

  uint32_t flags = ifa->ifa_flags; // overwritten by IFA_FLAGS if supported and present
#ifdef NDN_CXX_HAVE_IFA_FLAGS
  auto extFlags = attrs.getAttributeByType<uint32_t>(IFA_FLAGS);
  if (extFlags)
    flags = *extFlags;
#endif // NDN_CXX_HAVE_IFA_FLAGS

  NetworkAddress address(ifaFamilyToAddressFamily(ifa->ifa_family),
                         ipAddr,
                         broadcastAddr,
                         ifa->ifa_prefixlen,
                         ifaScopeToAddressScope(ifa->ifa_scope),
                         flags);
  BOOST_ASSERT(address.getFamily() != AddressFamily::UNSPECIFIED);

  if (nlmsg->nlmsg_type == RTM_NEWADDR)
    interface->addNetworkAddress(address);
  else if (nlmsg->nlmsg_type == RTM_DELADDR)
    interface->removeNetworkAddress(address);
}

void
NetworkMonitorImplNetlink::parseRouteMessage(const NetlinkMessage& nlmsg)
{
  // TODO
}

void
NetworkMonitorImplNetlink::parseErrorMessage(const NetlinkMessage& nlmsg)
{
  const nlmsgerr* err = nlmsg.getPayload<nlmsgerr>();
  if (err == nullptr) {
    NDN_LOG_WARN("malformed nlmsgerr");
    return;
  }

  if (err->error == 0) {
    // an error code of zero indicates an ACK message, not an error
    NDN_LOG_TRACE("ACK");
    return;
  }

  NDN_LOG_ERROR("NLMSG_ERROR: " << std::strerror(std::abs(err->error)));

#ifdef NDN_CXX_HAVE_NETLINK_EXT_ACK
  if (!(nlmsg->nlmsg_flags & NLM_F_ACK_TLVS))
    return;

  size_t errLen = NLMSG_LENGTH(sizeof(nlmsgerr));
  if (!(nlmsg->nlmsg_flags & NLM_F_CAPPED))
    errLen += err->msg.nlmsg_len - NLMSG_HDRLEN; // don't count the inner nlmsghdr twice

  if (nlmsg->nlmsg_len <= errLen)
    return;

  auto nla = reinterpret_cast<const nlattr*>(reinterpret_cast<const uint8_t*>(&*nlmsg) + errLen);
  auto attrs = NetlinkMessageAttributes<nlattr>(nla, nlmsg->nlmsg_len - errLen);
  auto msg = attrs.getAttributeByType<std::string>(NLMSGERR_ATTR_MSG);
  if (msg && !msg->empty())
    NDN_LOG_ERROR("kernel message: " << *msg);
#endif // NDN_CXX_HAVE_NETLINK_EXT_ACK
}

} // namespace net
} // namespace ndn
