/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023,  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 NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_DAEMON_FACE_NETWORK_PREDICATE_HPP
#define NFD_DAEMON_FACE_NETWORK_PREDICATE_HPP

#include "core/common.hpp"

#include <boost/operators.hpp>
#include <boost/property_tree/ptree_fwd.hpp>

#include <ndn-cxx/net/network-interface.hpp>

namespace nfd::face {

class NetworkPredicateBase : private boost::equality_comparable<NetworkPredicateBase>
{
public:
  NetworkPredicateBase();

  /**
   * \brief Set the whitelist to "*" and clear the blacklist.
   */
  void
  clear();

  void
  parseWhitelist(const boost::property_tree::ptree& list);

  void
  parseBlacklist(const boost::property_tree::ptree& list);

  void
  assign(std::initializer_list<std::pair<std::string, std::string>> whitelist,
         std::initializer_list<std::pair<std::string, std::string>> blacklist);

protected:
  // Explicitly declare the following four special member functions
  // to avoid -Wdeprecated-copy-with-dtor warnings from clang.

  NetworkPredicateBase(const NetworkPredicateBase&) = delete;

  NetworkPredicateBase(NetworkPredicateBase&&) = default;

  NetworkPredicateBase&
  operator=(const NetworkPredicateBase&) = delete;

  NetworkPredicateBase&
  operator=(NetworkPredicateBase&&) = default;

  // NetworkPredicateBase is not supposed to be used polymorphically, so we make the destructor
  // protected to prevent deletion of derived objects through a pointer to the base class,
  // which would be UB when the destructor is non-virtual.
  ~NetworkPredicateBase() = default;

private:
  virtual bool
  isRuleSupported(const std::string& key) = 0;

  virtual bool
  isRuleValid(const std::string& key, const std::string& value) = 0;

  void
  parseList(std::set<std::string>& set, const boost::property_tree::ptree& list, const std::string& section);

  void
  parseList(std::set<std::string>& set, std::initializer_list<std::pair<std::string, std::string>> list);

private: // non-member operators (hidden friends)
  friend bool
  operator==(const NetworkPredicateBase& lhs, const NetworkPredicateBase& rhs)
  {
    return lhs.m_whitelist == rhs.m_whitelist &&
           lhs.m_blacklist == rhs.m_blacklist;
  }

NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
  std::set<std::string> m_whitelist;
  std::set<std::string> m_blacklist;
};

/**
 * \brief Represents a predicate to accept or reject a ndn::net::NetworkInterface.
 *
 * The predicate consists of a whitelist and a blacklist. Whitelist and blacklist can contain,
 * in no particular order, interface names (e.g., `ifname eth0`), MAC addresses (e.g., `ether
 * 85:3b:4d:d3:5f:c2`), IPv4 and IPv6 subnets (e.g., `subnet 192.0.2.0/24` or `subnet
 * 2001:db8:2::/64`), or a wildcard (`*`) that matches all interfaces. A
 * ndn::net::NetworkInterface is accepted if it matches any entry in the whitelist and none of
 * the entries in the blacklist.
 */
class NetworkInterfacePredicate final : public NetworkPredicateBase
{
public:
  bool
  operator()(const ndn::net::NetworkInterface& netif) const;

private:
  bool
  isRuleSupported(const std::string& key) final;

  bool
  isRuleValid(const std::string& key, const std::string& value) final;
};

/**
 * \brief Represents a predicate to accept or reject an IP address.
 *
 * The predicate consists of a whitelist and a blacklist. Whitelist and blacklist can contain,
 * in no particular order, IPv4 and IPv6 subnets (e.g., `subnet 192.0.2.0/24` or `subnet
 * 2001:db8:2::/64`) or a wildcard (`*`) that matches all IP addresses. An IP address is
 * accepted if it matches any entry in the whitelist and none of the entries in the blacklist.
 */
class IpAddressPredicate final : public NetworkPredicateBase
{
public:
  bool
  operator()(const boost::asio::ip::address& address) const;

private:
  bool
  isRuleSupported(const std::string& key) final;

  bool
  isRuleValid(const std::string& key, const std::string& value) final;
};

} // namespace nfd::face

#endif // NFD_DAEMON_FACE_NETWORK_PREDICATE_HPP
