// Tests sending packets client -> server, then server -> client.
TEST_F(SocketTest, SendAndReceive) {
    ASSERT_TRUE(StartServer());
    ASSERT_TRUE(StartClient());

    EXPECT_TRUE(SendString(client_.get(), "foo"));
    EXPECT_EQ("foo", ReceiveString(server_.get()));

    EXPECT_TRUE(SendString(server_.get(), "bar baz"));
    EXPECT_EQ("bar baz", ReceiveString(client_.get()));
}
// Tests IPv6 client/server.
TEST_F(SocketTest, IPv6) {
    ASSERT_TRUE(StartServer());
    ASSERT_TRUE(StartClient("::1"));

    EXPECT_TRUE(SendString(client_.get(), "foo"));
    EXPECT_EQ("foo", ReceiveString(server_.get()));

    EXPECT_TRUE(SendString(server_.get(), "bar"));
    EXPECT_EQ("bar", ReceiveString(client_.get()));
}
// Tests sending packets client -> server, then server -> client.
TEST(SocketTest, TestSendAndReceive) {
    std::unique_ptr<Socket> server, client;

    for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
        ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));

        EXPECT_TRUE(SendString(client.get(), "foo"));
        EXPECT_TRUE(ReceiveString(server.get(), "foo"));

        EXPECT_TRUE(SendString(server.get(), "bar baz"));
        EXPECT_TRUE(ReceiveString(client.get(), "bar baz"));
    }
}
// Tests multiple clients sending to the same server.
TEST_F(SocketTest, MultipleClients) {
    ASSERT_TRUE(StartServer());
    ASSERT_TRUE(StartClient());
    ASSERT_TRUE(StartClient2());

    EXPECT_TRUE(SendString(client_.get(), "client"));
    EXPECT_TRUE(SendString(client2_.get(), "client2"));

    // Receive the packets and send a response for each (note that packets may be received
    // out-of-order).
    for (int i = 0; i < 2; ++i) {
        std::string received = ReceiveString(server_.get());
        EXPECT_TRUE(SendString(server_.get(), received + " response"));
    }

    EXPECT_EQ("client response", ReceiveString(client_.get()));
    EXPECT_EQ("client2 response", ReceiveString(client2_.get()));
}
// Tests receive overflow (the UDP packet is larger than the receive buffer).
TEST_F(SocketTest, ReceiveOverflow) {
    ASSERT_TRUE(StartServer());
    ASSERT_TRUE(StartClient());

    EXPECT_TRUE(SendString(client_.get(), "1234567890"));

    // This behaves differently on different systems; some give us a truncated UDP packet, others
    // will error out and not return anything at all.
    std::string rx_string = ReceiveString(server_.get(), 5);

    // If we didn't get an error then the packet should have been truncated.
    if (rx_string != kReceiveStringError) {
        EXPECT_EQ("12345", rx_string);
    }
}
// Tests sending and receiving large packets.
TEST_F(SocketTest, LargePackets) {
    std::string message(512, '\0');

    ASSERT_TRUE(StartServer());
    ASSERT_TRUE(StartClient());

    // Run through the test a few times.
    for (int i = 0; i < 10; ++i) {
        // Use a different message each iteration to prevent false positives.
        for (size_t j = 0; j < message.length(); ++j) {
            message[j] = static_cast<char>(i + j);
        }

        EXPECT_TRUE(SendString(client_.get(), message));
        EXPECT_EQ(message, ReceiveString(server_.get(), message.length()));
    }
}
// Tests sending and receiving large packets.
TEST(SocketTest, TestLargePackets) {
    std::string message(1024, '\0');
    std::unique_ptr<Socket> server, client;

    for (Socket::Protocol protocol : {Socket::Protocol::kUdp, Socket::Protocol::kTcp}) {
        ASSERT_TRUE(MakeConnectedSockets(protocol, &server, &client));

        // Run through the test a few times.
        for (int i = 0; i < 10; ++i) {
            // Use a different message each iteration to prevent false positives.
            for (size_t j = 0; j < message.length(); ++j) {
                message[j] = static_cast<char>(i + j);
            }

            EXPECT_TRUE(SendString(client.get(), message));
            EXPECT_TRUE(ReceiveString(server.get(), message));
        }
    }
}
void MsgHandlerJSON::Run() {
	std::string msg;
	syslog(LOG_INFO, "JSON message handler started");

	m_closed = false;

	while(IsRunning()) {
		// exit if connection was closed
		if(m_closed) {
			break;
		}

		// wait for string
		if(!ReceiveString(msg)) {
			continue;
		}

		std::cout << msg << std::endl;

		// check for http request
		if(msg.substr(0, 8) == "OPTIONS " && msg.size() > 8) {
			msg = msg.substr(8);
		}
		else if(msg.substr(0, 4) != "GET ") {
			continue;
		}

		std::string::size_type p = msg.rfind("HTTP/");

		if(p == std::string::npos) {
			continue;
		}

		msg = msg.substr(0, p);
		std::cout << "URI: " << msg << std::endl;

		// extract JSON query string
		p = msg.find("?");

		std::string url;
		std::string query;

		if(p > 0) {
			url = msg.substr(0, p);
		}

		if(p < msg.size() - 1) {
			query = URLDecode(msg.substr(p + 1));
		}

		std::cout << "URL: " << url << std::endl;
		std::cout << "QUERY: " << query << std::endl;

		// get message id
		while((url[0] > '9' || url[0] < '0') && url.size() > 1) {
			url = url.substr(1);
		}

		uint32_t msgid = atoi(url.c_str());
		MsgPacket* request = MsgPacketFromJSON(query, msgid);

		if(m_msgtype != 0) {
			request->setType(m_msgtype);
		}

		std::cout << "MSGID: " << request->getMsgID() << std::endl;
		std::cout << "MSGTYPE: " << request->getType() << std::endl;

		request->print();

		MsgPacket* response = new MsgPacket(request->getMsgID(), request->getType(), request->getUID());

		std::string jsonformat;
		std::string result;

		request->rewind();

		if(OnMessage(request, response)) {
			if(OnCustomJSONResponse(response, result)) {
				SendHTTPResponse(result);
			}
			else if(OnResponseFormat(response, jsonformat)) {
				result = MsgPacketToJSON(response, jsonformat);
				SendHTTPResponse(result);
			}
		}

		delete response;
		delete request;
	}
}