/*
 *  Copyright (C) 2021-2024 Savoir-faire Linux Inc.
 *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
 *
 *  This program 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.
 *
 *  This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <regex>

#include <condition_variable>
#include <asio/executor_work_guard.hpp>
#include <asio/io_context.hpp>

#include "opendht/dhtrunner.h"
#include "opendht/sockaddr.h"
#include "opendht/thread_pool.h"
#include "test_runner.h"
#include "upnp/upnp_context.h"
#include "ice_transport.h"
#include "ice_transport_factory.h"


namespace dhtnet {
namespace test {

class IceTest : public CppUnit::TestFixture
{
public:
    IceTest()
    {

    }
    ~IceTest() {}
    static std::string name() { return "Ice"; }
    void setUp();
    void tearDown();

    // For future tests with publicIp
    std::shared_ptr<dht::DhtRunner> dht_ {};
    std::unique_ptr<dhtnet::IpAddr> turnV4_ {};

    std::shared_ptr<asio::io_context> ioContext;
    std::shared_ptr<std::thread> ioContextRunner;
    std::shared_ptr<IceTransportFactory> factory;
    std::shared_ptr<upnp::UPnPContext> upnpContext;

private:
    void testRawIceConnection();
    void testTurnMasterIceConnection();
    void testTurnSlaveIceConnection();
    void testReceiveTooManyCandidates();
    void testCompleteOnFailure();

    CPPUNIT_TEST_SUITE(IceTest);
    CPPUNIT_TEST(testRawIceConnection);
    CPPUNIT_TEST(testTurnMasterIceConnection);
    CPPUNIT_TEST(testTurnSlaveIceConnection);
    CPPUNIT_TEST(testReceiveTooManyCandidates);
    CPPUNIT_TEST(testCompleteOnFailure);
    CPPUNIT_TEST_SUITE_END();
};

CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(IceTest, IceTest::name());

void
IceTest::setUp()
{
    if (!dht_) {
        dht_ = std::make_shared<dht::DhtRunner>();
        dht::DhtRunner::Config config {};
        dht::DhtRunner::Context context {};

        std::mutex mtx;
        std::unique_lock lk(mtx);
        std::condition_variable cv;
        context.publicAddressChangedCb = [&](std::vector<dht::SockAddr> addr) {
            if (addr.size() != 0)
                cv.notify_all();
        };

        dht_->run(0, config, std::move(context));
        dht_->bootstrap("bootstrap.jami.net:4222");
        // Wait for the DHT's public address to be available, otherwise the assertion that
        // `addr4.size() != 0` at the beginning of several of the tests will fail.
        cv.wait_for(lk, std::chrono::seconds(5), [&] {
            return dht_->getPublicAddress().size() != 0;
        });
    }
    if (!turnV4_) {
        turnV4_ = std::make_unique<dhtnet::IpAddr>("turn.jami.net", AF_INET);
    }
    if (!upnpContext) {
        if (!ioContext) {
            ioContext = std::make_shared<asio::io_context>();
            ioContextRunner = std::make_shared<std::thread>([&] {
                auto work = asio::make_work_guard(*ioContext);
                ioContext->run();
            });
        }
        upnpContext = std::make_shared<dhtnet::upnp::UPnPContext>(ioContext, nullptr);
    }
    if (!factory) {
        factory = std::make_shared<IceTransportFactory>();
    }
}


void
IceTest::tearDown()
{
    upnpContext->shutdown();
    ioContext->stop();
    if (ioContextRunner && ioContextRunner->joinable()) {
        ioContextRunner->join();
    }
    dht_.reset();
    turnV4_.reset();
}

void
IceTest::testRawIceConnection()
{
    dhtnet::IceTransportOptions ice_config;
    ice_config.upnpEnable = true;
    ice_config.tcpEnable = true;
    std::shared_ptr<dhtnet::IceTransport> ice_master, ice_slave;
    std::mutex mtx, mtx_create, mtx_resp, mtx_init;
    std::unique_lock lk {mtx}, lk_create {mtx_create}, lk_resp {mtx_resp},
        lk_init {mtx_init};
    std::condition_variable cv, cv_create, cv_resp, cv_init;
    std::string init = {};
    std::string response = {};
    bool iceMasterReady = false, iceSlaveReady = false;
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_master != nullptr;
            }));
            auto iceAttributes = ice_master->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_master->getLocalCandidates(1)) {
                icemsg << addr << "\n";
                fmt::print("Added local ICE candidate {}\n", addr);
            }
            init = icemsg.str();
            cv_init.notify_one();
            CPPUNIT_ASSERT(cv_resp.wait_for(lk_resp, std::chrono::seconds(10), [&] {
                return !response.empty();
            }));
            auto sdp = ice_master->parseIceCandidates(response);
            CPPUNIT_ASSERT(
                ice_master->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceMasterReady = ok;
        cv.notify_one();
    };
    ice_config.master = true;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;

    ice_master = factory->createTransport("master ICE");
    ice_master->initIceInstance(ice_config);
    cv_create.notify_all();
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_slave != nullptr;
            }));
            auto iceAttributes = ice_slave->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_slave->getLocalCandidates(1)) {
                icemsg << addr << "\n";
                fmt::print("Added local ICE candidate {}\n", addr);
            }
            response = icemsg.str();
            cv_resp.notify_one();
            CPPUNIT_ASSERT(
                cv_init.wait_for(lk_resp, std::chrono::seconds(10), [&] { return !init.empty(); }));
            auto sdp = ice_slave->parseIceCandidates(init);
            CPPUNIT_ASSERT(
                ice_slave->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceSlaveReady = ok;
        cv.notify_one();
    };
    ice_config.master = false;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;

    ice_slave = factory->createTransport("slave ICE");
    ice_slave->initIceInstance(ice_config);

    cv_create.notify_all();
    CPPUNIT_ASSERT(
        cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
}

void
IceTest::testTurnMasterIceConnection()
{
    const auto& addr4 = dht_->getPublicAddress(AF_INET);
    CPPUNIT_ASSERT(addr4.size() != 0);
    CPPUNIT_ASSERT(turnV4_);
    dhtnet::IceTransportOptions ice_config;
    ice_config.upnpEnable = true;
    ice_config.tcpEnable = true;
    std::shared_ptr<dhtnet::IceTransport> ice_master, ice_slave;
    std::mutex mtx, mtx_create, mtx_resp, mtx_init;
    std::condition_variable cv, cv_create, cv_resp, cv_init;
    std::string init = {};
    std::string response = {};
    bool iceMasterReady = false, iceSlaveReady = false;

    // Master
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            /*{
                std::unique_lock lk_create {mtx_create};
                CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                    return ice_master != nullptr;
                }));
            }*/
            auto iceAttributes = ice_master->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";

            for (const auto& addr : ice_master->getLocalCandidates(1)) {

                if (addr.find("host") == std::string::npos) {
                    // We only want to add relayed + public ip
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            {
                std::lock_guard lk {mtx_init};
                init = icemsg.str();
                cv_init.notify_one();
            }
            {
                std::unique_lock lk_resp {mtx_resp};
                CPPUNIT_ASSERT(cv_resp.wait_for(lk_resp, std::chrono::seconds(10), [&] {
                    return !response.empty();
                }));
                auto sdp = ice_master->parseIceCandidates(response);
                CPPUNIT_ASSERT(
                    ice_master->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
            }
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        std::lock_guard lk {mtx};
        iceMasterReady = ok;
        cv.notify_one();
    };
    ice_config.accountPublicAddr = dhtnet::IpAddr(*addr4[0].get());
    ice_config.accountLocalAddr = dhtnet::ip_utils::getLocalAddr(AF_INET);
    ice_config.turnServers.emplace_back(dhtnet::TurnServerInfo()
                                            .setUri(turnV4_->toString(true))
                                            .setUsername("ring")
                                            .setPassword("ring")
                                            .setRealm("ring"));
    ice_config.master = true;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    {
        std::unique_lock lk_create {mtx_create};
        ice_master = factory->createTransport("master ICE");
        ice_master->initIceInstance(ice_config);
        cv_create.notify_all();
    }

    // Slave
    ice_config.turnServers = {};
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            /*std::unique_lock lk_create {mtx_create};
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_slave != nullptr;
            }));*/
            auto iceAttributes = ice_slave->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_slave->getLocalCandidates(1)) {
                if (addr.find("host") == std::string::npos) {
                    // We only want to add relayed + public ip
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            {
                std::lock_guard lk {mtx_resp};
                response = icemsg.str();
                cv_resp.notify_one();
            }
            {
                std::unique_lock lk {mtx_init};
                CPPUNIT_ASSERT(
                    cv_init.wait_for(lk, std::chrono::seconds(10), [&] { return !init.empty(); }));
                auto sdp = ice_slave->parseIceCandidates(init);
                CPPUNIT_ASSERT(
                    ice_slave->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
            }
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        std::lock_guard lk {mtx};
        iceSlaveReady = ok;
        cv.notify_one();
    };
    ice_config.master = false;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    {
        std::unique_lock lk_create {mtx_create};
        ice_slave = factory->createTransport("slave ICE");
        ice_slave->initIceInstance(ice_config);
        cv_create.notify_all();
    }
    std::unique_lock lk {mtx};
    CPPUNIT_ASSERT(
        cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady; }));
    CPPUNIT_ASSERT(
        cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceSlaveReady; }));

    CPPUNIT_ASSERT(ice_master->getLocalAddress(1).toString(false) == turnV4_->toString(false));
}

void
IceTest::testTurnSlaveIceConnection()
{
    const auto& addr4 = dht_->getPublicAddress(AF_INET);
    CPPUNIT_ASSERT(addr4.size() != 0);
    CPPUNIT_ASSERT(turnV4_);
    dhtnet::IceTransportOptions ice_config;
    ice_config.upnpEnable = true;
    ice_config.tcpEnable = true;
    std::shared_ptr<dhtnet::IceTransport> ice_master, ice_slave;
    std::mutex mtx, mtx_create, mtx_resp, mtx_init;
    std::unique_lock lk {mtx}, lk_create {mtx_create}, lk_resp {mtx_resp},
        lk_init {mtx_init};
    std::condition_variable cv, cv_create, cv_resp, cv_init;
    std::string init = {};
    std::string response = {};
    bool iceMasterReady = false, iceSlaveReady = false;
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_master != nullptr;
            }));
            auto iceAttributes = ice_master->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_master->getLocalCandidates(1)) {
                if (addr.find("host") == std::string::npos) {
                    // We only want to add relayed + public ip
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            init = icemsg.str();
            cv_init.notify_one();
            CPPUNIT_ASSERT(cv_resp.wait_for(lk_resp, std::chrono::seconds(10), [&] {
                return !response.empty();
            }));
            auto sdp = ice_master->parseIceCandidates(response);
            CPPUNIT_ASSERT(
                ice_master->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceMasterReady = ok;
        cv.notify_one();
    };
    ice_config.accountPublicAddr = dhtnet::IpAddr(*addr4[0].get());
    ice_config.accountLocalAddr = dhtnet::ip_utils::getLocalAddr(AF_INET);
    ice_config.master = true;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    ice_master = factory->createTransport("master ICE");
    ice_master->initIceInstance(ice_config);
    cv_create.notify_all();
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_slave != nullptr;
            }));
            auto iceAttributes = ice_slave->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_slave->getLocalCandidates(1)) {
                if (addr.find("host") == std::string::npos) {
                    // We only want to add relayed + public ip
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            response = icemsg.str();
            cv_resp.notify_one();
            CPPUNIT_ASSERT(
                cv_init.wait_for(lk_resp, std::chrono::seconds(10), [&] { return !init.empty(); }));
            auto sdp = ice_slave->parseIceCandidates(init);
            CPPUNIT_ASSERT(
                ice_slave->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceSlaveReady = ok;
        cv.notify_one();
    };
    ice_config.turnServers.emplace_back(dhtnet::TurnServerInfo()
                                            .setUri(turnV4_->toString(true))
                                            .setUsername("ring")
                                            .setPassword("ring")
                                            .setRealm("ring"));
    ice_config.master = false;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    ice_slave = factory->createTransport("slave ICE");
    ice_slave->initIceInstance(ice_config);
    cv_create.notify_all();
    CPPUNIT_ASSERT(
        cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
    CPPUNIT_ASSERT(ice_slave->getLocalAddress(1).toString(false) == turnV4_->toString(false));
}

void
IceTest::testReceiveTooManyCandidates()
{
    const auto& addr4 = dht_->getPublicAddress(AF_INET);
    CPPUNIT_ASSERT(addr4.size() != 0);
    CPPUNIT_ASSERT(turnV4_);
    dhtnet::IceTransportOptions ice_config;
    ice_config.upnpEnable = true;
    ice_config.tcpEnable = true;
    std::shared_ptr<dhtnet::IceTransport> ice_master, ice_slave;
    std::mutex mtx, mtx_create, mtx_resp, mtx_init;
    std::condition_variable cv, cv_create, cv_resp, cv_init;
    std::string init = {};
    std::string response = {};
    bool iceMasterReady = false, iceSlaveReady = false;
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            {
                std::unique_lock lk_create {mtx_create};
                CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                    return ice_master != nullptr;
                }));
            }
            auto iceAttributes = ice_master->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_master->getLocalCandidates(1)) {
                icemsg << addr << "\n";
                fmt::print("Added local ICE candidate {}\n", addr);
            }
            init = icemsg.str();
            cv_init.notify_one();
            {
                std::unique_lock lk_resp {mtx_resp};
                CPPUNIT_ASSERT(cv_resp.wait_for(lk_resp, std::chrono::seconds(10), [&] {
                    return !response.empty();
                }));
                auto sdp = ice_master->parseIceCandidates(response);
                CPPUNIT_ASSERT(
                    ice_master->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
            }
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceMasterReady = ok;
        cv.notify_one();
    };
    ice_config.accountPublicAddr = dhtnet::IpAddr(*addr4[0].get());
    ice_config.accountLocalAddr = dhtnet::ip_utils::getLocalAddr(AF_INET);
    ice_config.turnServers.emplace_back(dhtnet::TurnServerInfo()
                                            .setUri(turnV4_->toString(true))
                                            .setUsername("ring")
                                            .setPassword("ring")
                                            .setRealm("ring"));
    ice_config.master = true;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;

    ice_master = factory->createTransport("master ICE");
    ice_master->initIceInstance(ice_config);
    cv_create.notify_all();
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            {
                std::unique_lock lk_create {mtx_create};
                CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                    return ice_slave != nullptr;
                }));
            }
            auto iceAttributes = ice_slave->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_master->getLocalCandidates(1)) {
                icemsg << addr << "\n";
                fmt::print("Added local ICE candidate {}\n", addr);
            }
            for (auto i = 0; i < std::min(256, PJ_ICE_ST_MAX_CAND); ++i) {
                icemsg << "Hc0a800a5 1 TCP 2130706431 192.168.0." << i
                       << " 43613 typ host tcptype passive"
                       << "\n";
                icemsg << "Hc0a800a5 1 TCP 2130706431 192.168.0." << i
                       << " 9 typ host tcptype active"
                       << "\n";
            }
            {
                std::lock_guard lk_resp {mtx_resp};
                response = icemsg.str();
                cv_resp.notify_one();
            }
            std::unique_lock lk_init {mtx_init};
            CPPUNIT_ASSERT(
                cv_init.wait_for(lk_init, std::chrono::seconds(10), [&] { return !init.empty(); }));
            auto sdp = ice_slave->parseIceCandidates(init);
            CPPUNIT_ASSERT(
                ice_slave->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceSlaveReady = ok;
        cv.notify_one();
    };
    ice_config.master = false;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;

    ice_slave = factory->createTransport("slave ICE");
    ice_slave->initIceInstance(ice_config);
    cv_create.notify_all();

    std::unique_lock lk {mtx};
    CPPUNIT_ASSERT(
        cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
}

void
IceTest::testCompleteOnFailure()
{
    const auto& addr4 = dht_->getPublicAddress(AF_INET);
    CPPUNIT_ASSERT(addr4.size() != 0);
    CPPUNIT_ASSERT(turnV4_);
    dhtnet::IceTransportOptions ice_config;
    ice_config.upnpEnable = true;
    ice_config.tcpEnable = true;
    std::shared_ptr<dhtnet::IceTransport> ice_master, ice_slave;
    std::mutex mtx, mtx_create, mtx_resp, mtx_init;
    std::unique_lock lk {mtx}, lk_create {mtx_create}, lk_resp {mtx_resp},
        lk_init {mtx_init};
    std::condition_variable cv, cv_create, cv_resp, cv_init;
    std::string init = {};
    std::string response = {};
    bool iceMasterNotReady = false, iceSlaveNotReady = false;
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_master != nullptr;
            }));
            auto iceAttributes = ice_master->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_master->getLocalCandidates(1)) {
                if (addr.find("relay") != std::string::npos) {
                    // We only want to relayed and modify the rest (to have CONNREFUSED)
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            init = icemsg.str();
            cv_init.notify_one();
            CPPUNIT_ASSERT(cv_resp.wait_for(lk_resp, std::chrono::seconds(10), [&] {
                return !response.empty();
            }));
            auto sdp = ice_master->parseIceCandidates(response);
            CPPUNIT_ASSERT(
                ice_master->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceMasterNotReady = !ok;
        cv.notify_one();
    };
    ice_config.accountPublicAddr = dhtnet::IpAddr(*addr4[0].get());
    ice_config.accountLocalAddr = dhtnet::ip_utils::getLocalAddr(AF_INET);
    ice_config.master = true;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    ice_master = factory->createTransport("master ICE");
    ice_master->initIceInstance(ice_config);
    cv_create.notify_all();
    ice_config.onInitDone = [&](bool ok) {
        CPPUNIT_ASSERT(ok);
        dht::ThreadPool::io().run([&] {
            CPPUNIT_ASSERT(cv_create.wait_for(lk_create, std::chrono::seconds(10), [&] {
                return ice_slave != nullptr;
            }));
            auto iceAttributes = ice_slave->getLocalAttributes();
            std::stringstream icemsg;
            icemsg << iceAttributes.ufrag << "\n";
            icemsg << iceAttributes.pwd << "\n";
            for (const auto& addr : ice_slave->getLocalCandidates(1)) {
                if (addr.find("relay") != std::string::npos) {
                    // We only want to relayed and modify the rest (to have CONNREFUSED)
                    icemsg << addr << "\n";
                    fmt::print("Added local ICE candidate {}\n", addr);
                } else {
                    // Replace host by non existing IP (we still need host to not fail the start)
                    std::regex e("((?:[0-9]{1,3}\\.){3}[0-9]{1,3})");
                    auto newaddr = std::regex_replace(addr, e, "100.100.100.100");
                    if (newaddr != addr)
                        icemsg << newaddr << "\n";
                }
            }
            response = icemsg.str();
            cv_resp.notify_one();
            CPPUNIT_ASSERT(
                cv_init.wait_for(lk_resp, std::chrono::seconds(10), [&] { return !init.empty(); }));
            auto sdp = ice_slave->parseIceCandidates(init);
            CPPUNIT_ASSERT(
                ice_slave->startIce({sdp.rem_ufrag, sdp.rem_pwd}, std::move(sdp.rem_candidates)));
        });
    };
    ice_config.onNegoDone = [&](bool ok) {
        iceSlaveNotReady = !ok;
        cv.notify_one();
    };
    ice_config.turnServers.emplace_back(dhtnet::TurnServerInfo()
                                            .setUri(turnV4_->toString(true))
                                            .setUsername("ring")
                                            .setPassword("ring")
                                            .setRealm("ring"));
    ice_config.master = false;
    ice_config.streamsCount = 1;
    ice_config.compCountPerStream = 1;
    ice_config.upnpContext = upnpContext;
    ice_config.factory = factory;
    ice_slave = factory->createTransport("slave ICE");
    ice_slave->initIceInstance(ice_config);
    cv_create.notify_all();
    // Check that nego failed and callback called
    CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(120), [&] {
        return iceMasterNotReady && iceSlaveNotReady;
    }));
}

} // namespace test
}

JAMI_TEST_RUNNER(dhtnet::test::IceTest::name())
