/*
 *  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/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 {};
        dht_->run(0, config, std::move(context));
        dht_->bootstrap("bootstrap.jami.net:4222");
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
    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>([&] { 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lk_resp {mtx_resp};
                response = icemsg.str();
                cv_resp.notify_one();
            }
            std::unique_lock<std::mutex> 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<std::mutex> 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<std::mutex> 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())
