/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2023 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.
 */

#include "ndn-cxx/net/dns.hpp"

#include "tests/boost-test.hpp"
#include "tests/unit/net/network-configuration-detector.hpp"

#include <boost/asio/io_context.hpp>

namespace ndn::tests {

using namespace ndn::dns;
namespace ip = boost::asio::ip;

class DnsFixture
{
public:
  void
  onSuccess(const boost::asio::ip::address& resolvedAddress,
            const boost::asio::ip::address& expectedAddress,
            bool isValid,
            bool shouldCheckAddress = false)
  {
    ++m_nSuccesses;

    if (!isValid) {
      BOOST_ERROR("Resolved to " + resolvedAddress.to_string() + ", but should have failed");
    }

    BOOST_CHECK_EQUAL(resolvedAddress.is_v4(), expectedAddress.is_v4());

    // checking address is not deterministic and should be enabled only
    // if only one IP address will be returned by resolution
    if (shouldCheckAddress) {
      BOOST_CHECK_EQUAL(resolvedAddress, expectedAddress);
    }
  }

  void
  onFailure(bool shouldFail)
  {
    ++m_nFailures;
    BOOST_CHECK_MESSAGE(shouldFail, "Resolution should not have failed");
  }

protected:
  int m_nFailures = 0;
  int m_nSuccesses = 0;
  boost::asio::io_context m_ioCtx;
};

BOOST_AUTO_TEST_SUITE(Net)
BOOST_FIXTURE_TEST_SUITE(TestDns, DnsFixture)

BOOST_AUTO_TEST_CASE(Failure)
{
  SKIP_IF_IP_UNAVAILABLE();

  asyncResolve("nothost.nothost.nothost.arpa",
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), false, false),
               [this] (auto&&...) { onFailure(true); },
               m_ioCtx); // should fail

  m_ioCtx.run();
  BOOST_CHECK_EQUAL(m_nFailures, 1);
  BOOST_CHECK_EQUAL(m_nSuccesses, 0);
}

BOOST_AUTO_TEST_CASE(Ipv4)
{
  SKIP_IF_IPV4_UNAVAILABLE();

  asyncResolve("192.0.2.1",
               std::bind(&DnsFixture::onSuccess, this, _1, ip::make_address_v4("192.0.2.1"), true, true),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx);

  m_ioCtx.run();
  BOOST_CHECK_EQUAL(m_nFailures, 0);
  BOOST_CHECK_EQUAL(m_nSuccesses, 1);
}

BOOST_AUTO_TEST_CASE(Ipv6)
{
  SKIP_IF_IPV6_UNAVAILABLE();

  asyncResolve("ipv6.google.com", // only IPv6 address should be available
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx);

  asyncResolve("2001:db8:3f9:0:3025:ccc5:eeeb:86d3",
               std::bind(&DnsFixture::onSuccess, this, _1,
                         ip::make_address_v6("2001:db8:3f9:0:3025:ccc5:eeeb:86d3"), true, true),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx);

  m_ioCtx.run();
  BOOST_CHECK_EQUAL(m_nFailures, 0);
  BOOST_CHECK_EQUAL(m_nSuccesses, 2);
}

BOOST_AUTO_TEST_CASE(WithAddressSelector)
{
  SKIP_IF_IPV4_UNAVAILABLE();
  SKIP_IF_IPV6_UNAVAILABLE();

  asyncResolve("named-data.net",
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), true, false),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx, Ipv4Only());

  asyncResolve("a.root-servers.net",
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v4(), true, false),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx, Ipv4Only()); // request IPv4 address

  asyncResolve("a.root-servers.net",
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx, Ipv6Only()); // request IPv6 address

  asyncResolve("ipv6.google.com", // only IPv6 address should be available
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), true, false),
               [this] (auto&&...) { onFailure(false); },
               m_ioCtx, Ipv6Only());

  asyncResolve("ipv6.google.com", // only IPv6 address should be available
               std::bind(&DnsFixture::onSuccess, this, _1, ip::address_v6(), false, false),
               [this] (auto&&...) { onFailure(true); },
               m_ioCtx, Ipv4Only()); // should fail

  m_ioCtx.run();
  BOOST_CHECK_EQUAL(m_nFailures, 1);
  BOOST_CHECK_EQUAL(m_nSuccesses, 4);
}

BOOST_AUTO_TEST_SUITE_END() // TestDns
BOOST_AUTO_TEST_SUITE_END() // Net

} // namespace ndn::tests
