#include <boost/asio.hpp>

using boost::asio::ip::tcp;

 

#include <mutex>
#include <boost/lexical_cast.hpp>
 

using socket_t = boost::asio::ip::tcp::socket;
 
 void accept_conncections_from_Pb(boost::asio::io_context&io_context, std::vector<socket_t>& socketsPb, int port, size_t j)
{
 	 tcp::acceptor acceptor_a(io_context, tcp::endpoint(tcp::v4(), port));
	 tcp::socket sb_a(acceptor_a.accept());
	 socketsPb[j] = std::move(sb_a); 
}


void make_connections(bool& party, const std::string host1, 
								 const std::string host2, boost::asio::io_context&io_context,  std::vector<socket_t>& socketsPb, std::vector<socket_t>& socketsP2, 	std::vector<int> ports, std::vector<int> ports2_1,	std::vector<int> ports2_0, size_t number_of_sockets)
{
	    tcp::resolver resolver(io_context);

		for(size_t j = 0; j < number_of_sockets + 1; ++j)
 	{
 		tcp::socket emptysocket(io_context);
 		socketsPb.emplace_back(std::move(emptysocket));
 	}
	
	socketsPb.reserve(number_of_sockets + 1);

	for(size_t j = 0; j < number_of_sockets; ++j) 
	{
		int port = 6000;
		ports.push_back(port + j);
	}
	

	for(size_t j = 0; j < number_of_sockets; ++j) 
	{
		int port = 20000;
		ports2_0.push_back(port + j);
	}


	for(size_t j = 0; j < number_of_sockets; ++j) 
	{
		int port = 40000;
		ports2_1.push_back(port + j);
	}


	#if (PARTY == 0)    
		
		party = false;
		for(size_t j = 0; j < number_of_sockets; ++j)
		{
		tcp::socket sb_a(io_context);
		boost::asio::connect(sb_a, resolver.resolve({host2, std::to_string(ports2_0[j])}));
		socketsP2.emplace_back(std::move(sb_a)); 
		}
	
		for(size_t j = 0; j < number_of_sockets; ++j)
		{
		tcp::socket sb_a(io_context);
		boost::asio::connect(sb_a, resolver.resolve({host1, std::to_string(ports[j])}));
		socketsPb[j] = std::move(sb_a); 
		}

	#else	
		party = true;	

		for(size_t j = 0; j < number_of_sockets; ++j)
		{
		tcp::socket sb_a(io_context);
		boost::asio::connect(sb_a, resolver.resolve({host2, std::to_string(ports2_1[j])}));
		socketsP2.emplace_back(std::move(sb_a)); 
		}
	
		boost::asio::thread_pool pool_connections(number_of_sockets); 
	
		for(size_t j = 0; j < number_of_sockets; ++j)
		{
		boost::asio::post(pool_connections, std::bind(accept_conncections_from_Pb,  std::ref(io_context), std::ref(socketsPb), ports[j],  j));
		}
	
	pool_connections.join();
	#endif
}