#include <scpp_os.hpp>
#include <iostream>
#include <scpp_thread.hpp>
#include <scpp_socket.hpp>
#include <scpp_unittest.hpp>

using namespace scpp;


/***
 * Socket 単体テスト
 */
class InetAddressTest : public TestCase
{
 	void suite()
 	{
 	//	RUN_TEST(testException);
	}
};

// class SocketServer : public Thread
// {
// 	public:
// 		void run()
// 		{
// 			Socket server;
// 			Socket client1;
// 			Socket client2;
// 			Socket client3;
// 			try
// 			{
// 				server.bind("::1", 9999);
// 				server.listen(10);
// 				server.accept(&client1);
// 				server.accept(&client2);
// 				server.accept(&client3);
// 				Thread::sleep(50);
// 				client1.close();
// 				client2.close();
// 				client3.close();
// 				server.close();
// 			}
// 			catch (SocketException& e)
// 			{
// 				Assertion::fail();
// 			}
// 		}
// 
// };
// 
// 
// class SocketServerRecv : public Thread
// {
// 	public:
// 		void run()
// 		{
// 			Socket  server;
// 			Socket  client;
// 			char    buff[1024];
// 			ssize_t readSize;
// 			try
// 			{
// 				server.bind("127.0.0.1", 9997);
// 				server.listen(10);
// 
// 				SocketSet readfd;
// 				readfd.add(server);
// 
// 				Socket::select(&readfd, 0, 0, 0);
// 				server.accept(&client);
// 				readSize = client.read(buff, sizeof(buff));
// 				Assertion::assertEquals('A', buff[0]);
// 				Assertion::assertEquals('B', buff[1]);
// 				Assertion::assertEquals('C', buff[2]);
// 				client.close();
// 				server.close();
// 			}
// 			 catch (SocketException& e)
// 			 {
// 				 Assertion::fail();
// 			 }
// 		}
// 
// };
// 
// 
// class DummySocket : public Socket
// {
// 	public:
// 		DummySocket() : Socket() {}
// 		~DummySocket() {}
// 		void test()
// 		{
// 			setRemoteAddress(0, 0);
// 			setLocalAddress(0, 0);
// 			Assertion::assertEquals("", getAddress());
// 			Assertion::assertEquals("", getPort());
// 			Assertion::assertEquals("", getLocalAddress());
// 			Assertion::assertEquals("", getLocalPort());
// 
// 		}
// };
// 
// /***
//  * Socket 単体テスト
//  */
// class SocketTest : public TestCase
// {
// 	public:
// 		SocketTest() {}
// 		~SocketTest() {}
// 
// 		void testException()
// 		{
// 			SocketException e1;
// 			SocketException e2("mag");
// 			SocketException e3(e1);
// 		}
// 
// 		void testSocket()
// 		{
// 			SocketServer serverThread;
// 			serverThread.start();
// 
// 			Thread::sleep(100);
// 			Socket sock1;
// 			Socket sock2;
// 			Socket sock3;
// 			try
// 			{
// 				sock1.connect("::1", 9999, "::1", 9998);
// 				Assertion::assertEquals("::1" , sock1.getAddress());
// 				Assertion::assertEquals("9999", sock1.getPort());
// 				Assertion::assertEquals("::1" , sock1.getLocalAddress());
// 				Assertion::assertEquals("9998", sock1.getLocalPort());
// 
// 				sock2.connect("::1", 9999, "::1");
// 				sock3.connect("::1", 9999);
// 
// 
// 				Thread::sleep(100);
// 				sock1.close();
// 				sock2.close();
// 				sock3.close();
// 			}
// 			catch (SocketException& e)
// 			{
// 				std::cout << e.what() << std::endl;
// 				Assertion::fail();
// 			}
// 			serverThread.join();
// 
// 		}
// 
// 		void testBindError()
// 		{
// 			Socket sock;
// 			try
// 			{
// 				sock.bind("111.111.111.111", 12345);
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 
// 			try
// 			{
// 				sock.listen(10);
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 
// 			try
// 			{
// 				Socket svr;
// 				svr.bind("::1", "1");
// 				sock.connect("xxxxx", "xyz", "::1", "1");
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 		}
// 
// 
// 		void testConnectError()
// 		{
// 			Socket sock;
// 			try
// 			{
// 				sock.connect("127.0.0.1", 1);
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 
// 			try
// 			{
// 				sock.connect("127.0.0.1", 1, "127.0.0.1", 2);
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 		}
// 
// 
// 		void testInvalidAddress()
// 		{
// 			Socket sock;
// 			try
// 			{
// 				sock.connect("hogehuga", "abc");
// 				Assertion::fail();
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 
// 			try
// 			{
// 				sock.bind("hogehuga", "abc");
// 			}
// 			catch (SocketException& e)
// 			{
// 				// ok
// 			}
// 
// 
// 		}
// 
// 		void testDummySocket()
// 		{
// 			DummySocket dsock;
// 			dsock.test();
// 		}
// 
// 
// 		void testSendRecv()
// 		{
// 			SocketServerRecv recvThread;
// 			recvThread.start();
// 			Thread::sleep(10);
// 			try
// 			{
// 				char buff[5];
// 				buff[0] = 'A';
// 				buff[1] = 'B';
// 				buff[2] = 'C';
// 				buff[3] = '\0';
// 				Socket client;
// 				client.connect("127.0.0.1", 9997);
// 
// 				SocketSet writefd;
// 				writefd.add(client);
// 
// 				Socket::select(0, &writefd, &writefd, 0);
// 
// 				client.write(buff, 4);
// 				client.close();
// 			}
// 			catch (SocketException& e)
// 			{
// 				std::cout << e.what() << std::endl;
// 				Assertion::fail();
// 			}
// 
// 			recvThread.join();
// 		}
// 
// 
// 		void testDatagramSocket()
// 		{
// 			DatagramSocket dsock;
// 			dsock.close();
// 		}
// 	
// 
// 
// 		void suite()
// 		{
// 			RUN_TEST(testException);
// 			RUN_TEST(testSocket);
// 			RUN_TEST(testBindError);
// 			RUN_TEST(testConnectError);
// 			RUN_TEST(testInvalidAddress);
// 			RUN_TEST(testDummySocket);
// 			RUN_TEST(testDatagramSocket);
// 			RUN_TEST(testSendRecv);
// 
// 		}
// 
// 
//};

