/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017 Regents of the University of California,
 *                         Arizona Board of Regents,
 *                         Colorado State University,
 *                         University Pierre & Marie Curie, Sorbonne University,
 *                         Washington University in St. Louis,
 *                         Beijing Institute of Technology,
 *                         The University of Memphis.
 *
 * 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.
 */

#include "ethernet.hpp"

#include <boost/functional/hash.hpp>

#include <stdio.h>
#include <ostream>

namespace ndn {
namespace util {
namespace ethernet {

Address::Address()
{
  fill(0);
}

Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
{
  data()[0] = a1;
  data()[1] = a2;
  data()[2] = a3;
  data()[3] = a4;
  data()[4] = a5;
  data()[5] = a6;
}

Address::Address(const uint8_t octets[ADDR_LEN])
{
  std::copy(octets, octets + size(), begin());
}

bool
Address::isBroadcast() const
{
  return *this == getBroadcastAddress();
}

bool
Address::isMulticast() const
{
  return (at(0) & 1) != 0;
}

bool
Address::isNull() const
{
  return *this == Address();
}

std::string
Address::toString(char sep) const
{
  char s[18]; // 12 digits + 5 separators + null terminator

  // - apparently gcc-4.6 does not support the 'hh' type modifier
  // - std::snprintf not found in some environments
  //   https://redmine.named-data.net/issues/2299 for more information
  snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
           at(0), sep, at(1), sep, at(2), sep, at(3), sep, at(4), sep, at(5));

  return std::string(s);
}

Address
Address::fromString(const std::string& str)
{
  Address a;
  unsigned short temp[a.size()];
  char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
  int n = 0; // num of chars read from the input string

  // apparently gcc-4.6 does not support the 'hh' type modifier
  int ret = std::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
                        &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
                        &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);

  if (ret < 11 || static_cast<size_t>(n) != str.length())
    return Address();

  for (size_t i = 0; i < a.size(); ++i)
    {
      // check that all separators are actually the same char (: or -)
      if (i < 5 && sep[i][0] != sep[0][0])
        return Address();

      // check that each value fits into a uint8_t
      if (temp[i] > 0xFF)
        return Address();

      a[i] = static_cast<uint8_t>(temp[i]);
    }

  return a;
}

Address
getBroadcastAddress()
{
  return { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
}

Address
getDefaultMulticastAddress()
{
  return { 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA };
}

std::ostream&
operator<<(std::ostream& o, const Address& a)
{
  return o << a.toString();
}

} // namespace ethernet
} // namespace util
} // namespace ndn

std::size_t
std::hash<ndn::util::ethernet::Address>::operator()(const ndn::util::ethernet::Address& a) const noexcept
{
  return boost::hash_range(a.cbegin(), a.cend());
}
