/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 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-interface.hpp"
#include "detail/linux-if-constants.hpp"
#include "logger.hpp"
#include "string-helper.hpp"

#include <net/if.h>

NDN_LOG_INIT(ndn.NetworkMonitor);

namespace ndn {
namespace util {

NetworkInterface::NetworkInterface()
  : m_index(0)
  , m_type(InterfaceType::UNKNOWN)
  , m_flags(0)
  , m_state(InterfaceState::UNKNOWN)
  , m_mtu(0)
{
}

bool
NetworkInterface::addNetworkAddress(const NetworkAddress& address)
{
  if (!address.getIp().is_unspecified()) {
    // need to erase the existing address before inserting
    // because the address flags may have changed
    bool isNew = m_netAddresses.erase(address) == 0;
    m_netAddresses.insert(address);
    if (isNew) {
      NDN_LOG_DEBUG("added address " << address << " to " << m_name);
      onAddressAdded(address);
      return true;
    }
  }
  return false;
}

bool
NetworkInterface::removeNetworkAddress(const NetworkAddress& address)
{
  if (m_netAddresses.erase(address) > 0) {
    NDN_LOG_DEBUG("removed address " << address << " from " << m_name);
    onAddressRemoved(address);
    return true;
  }
  return false;
}

void
NetworkInterface::setIndex(int index)
{
  m_index = index;
}

void
NetworkInterface::setName(const std::string& name)
{
  BOOST_ASSERT(!name.empty());
  m_name = name;
}

void
NetworkInterface::setType(InterfaceType type)
{
  m_type = type;
}

void
NetworkInterface::setFlags(uint32_t flags)
{
  m_flags = flags;
}

void
NetworkInterface::setState(InterfaceState state)
{
  if (m_state != state) {
    std::swap(m_state, state);
    onStateChanged(state, m_state);
  }
}

void
NetworkInterface::setMtu(uint32_t mtu)
{
  if (m_mtu != mtu) {
    std::swap(m_mtu, mtu);
    onMtuChanged(mtu, m_mtu);
  }
}

void
NetworkInterface::setEthernetAddress(const ethernet::Address& address)
{
  m_etherAddress = address;
}

void
NetworkInterface::setEthernetBroadcastAddress(const ethernet::Address& address)
{
  m_etherBrdAddress = address;
}

std::ostream&
operator<<(std::ostream& os, InterfaceType type)
{
  switch (type) {
    case InterfaceType::UNKNOWN:
      return os << "unknown";
    case InterfaceType::LOOPBACK:
      return os << "loopback";
    case InterfaceType::ETHERNET:
      return os << "ether";
  }
  return os;
}

std::ostream&
operator<<(std::ostream& os, InterfaceState state)
{
  switch (state) {
    case InterfaceState::UNKNOWN:
      return os << "unknown";
    case InterfaceState::DOWN:
      return os << "down";
    case InterfaceState::NO_CARRIER:
      return os << "no-carrier";
    case InterfaceState::DORMANT:
      return os << "dormant";
    case InterfaceState::RUNNING:
      return os << "running";
  }
  return os;
}

static void
printFlag(std::ostream& os, uint32_t& flags, uint32_t flagVal, const char* flagStr)
{
  if (flags & flagVal) {
    flags &= ~flagVal;
    os << flagStr << (flags ? "," : "");
  }
}

std::ostream&
operator<<(std::ostream& os, const NetworkInterface& netif)
{
  os << netif.getIndex() << ": " << netif.getName() << ": ";

  auto flags = netif.getFlags();
  os << "<";
#define PRINT_IFF(flag) printFlag(os, flags, IFF_##flag, #flag)
  PRINT_IFF(UP);
  PRINT_IFF(BROADCAST);
  PRINT_IFF(DEBUG);
  PRINT_IFF(LOOPBACK);
  PRINT_IFF(POINTOPOINT);
#if defined(IFF_NOTRAILERS)
  PRINT_IFF(NOTRAILERS);
#endif
  PRINT_IFF(RUNNING);
  PRINT_IFF(NOARP);
  PRINT_IFF(PROMISC);
  PRINT_IFF(ALLMULTI);
  PRINT_IFF(MULTICAST);
#if defined(__linux__)
  PRINT_IFF(MASTER);
  PRINT_IFF(SLAVE);
  PRINT_IFF(PORTSEL);
  PRINT_IFF(AUTOMEDIA);
  PRINT_IFF(DYNAMIC);
#elif defined(__APPLE__) || defined(__FreeBSD__)
  PRINT_IFF(OACTIVE);
  PRINT_IFF(SIMPLEX);
  PRINT_IFF(LINK0);
  PRINT_IFF(LINK1);
  PRINT_IFF(LINK2);
#endif
#if defined(__FreeBSD__)
  PRINT_IFF(CANTCONFIG);
  PRINT_IFF(PPROMISC);
  PRINT_IFF(MONITOR);
  PRINT_IFF(STATICARP);
  PRINT_IFF(DYING);
  PRINT_IFF(RENAMING);
#endif
#undef PRINT_IFF
#if defined(__linux__)
#define PRINT_IF_FLAG(flag) printFlag(os, flags, linux_if::FLAG_##flag, #flag)
  PRINT_IF_FLAG(LOWER_UP);
  PRINT_IF_FLAG(DORMANT);
  PRINT_IF_FLAG(ECHO);
#undef PRINT_IF_FLAG
#endif
  if (flags) {
    // print unknown flags in hex
    os << AsHex{flags};
  }
  os << ">";

  os << " state " << netif.getState() << " mtu " << netif.getMtu() << "\n"
     << "    link/" << netif.getType() << " " << netif.getEthernetAddress()
     << " brd " << netif.getEthernetBroadcastAddress() << "\n";

  for (const auto& addr : netif.getNetworkAddresses()) {
    os << "    " << (addr.getFamily() == AddressFamily::V4 ? "inet " : "inet6 ") << addr;
    if (netif.canBroadcast() && !addr.getBroadcast().is_unspecified())
      os << " brd " << addr.getBroadcast();
    os << " scope " << addr.getScope() << "\n";
  }

  return os;
}

} // namespace util
} // namespace ndn
