package net.tomp2p.connection;

import net.tomp2p.message.Message;
import net.tomp2p.rpc.RPC;

/**
 * Default sending behavior for UDP and TCP messages. Depending whether the recipient is relayed, slow and on
 * the message size, decisions can be made here.
 * 
 * @author Nico Rutishauser
 *
 */
public class DefaultSendBehavior implements SendBehavior {

	@Override
	public SendMethod tcpSendBehavior(Message message) {
		if(message.recipient().equals(message.sender())) {
			// shortcut, just send to yourself
			return SendMethod.SELF;
		}
		
		if (message.recipient().isRelayed()) {
			if (message.sender().isRelayed()) {
				// reverse connection is not possible because both peers are relayed. Thus send the message to
				// one of the receiver's relay peers
				return SendMethod.RELAY;
			} else if (message.recipient().isSlow()) {
				// the recipient is a slow peer (i.e. a mobile device). Send it to the relay such that this
				// one can handle latency and buffer multiple requests
				return SendMethod.RELAY;
			} else {
				// TODO check the message size. If > 1500bytes, use RCON, otherwise use Relay peer
				return SendMethod.RCON;
			}
		} else {
			// send directly
			return SendMethod.DIRECT;
		}
	}

	@Override
	public SendMethod udpSendBehavior(Message message) throws UnsupportedOperationException {
		if(message.recipient().equals(message.sender())) {
			// shortcut, just send to yourself
			return SendMethod.SELF;
		}
		
		if (message.recipient().isRelayed()) {
			if (message.command() == RPC.Commands.NEIGHBOR.getNr() || message.command() == RPC.Commands.PING.getNr()) {
				return SendMethod.RELAY;
			} else {
				throw new UnsupportedOperationException(
						"Tried to send UDP message to unreachable peers. Only TCP messages can be sent to unreachable peers");
			}
		} else {
			return SendMethod.DIRECT;
		}
	}
}

@@ -350,16 +350,56 @@
 vior %7B%0A%0A
+%09private static final int MTU = 1500;%0A%09%0A
 %09@Overri
@@ -1082,115 +1082,221 @@
 %09// 
-TODO check the message size. If %3E 1500bytes, use RCON, otherwise use Relay peer%0A%09%09%09%09return SendMethod.RCON;
+Messages with small size can be sent over relay, other messages should be sent directly (more efficient)%0A%09%09%09%09if(message.size() %3E MTU) %7B%0A%09%09%09%09%09return SendMethod.RCON;%0A%09%09%09%09%7D else %7B%0A%09%09%09%09%09return SendMethod.RELAY;%0A%09%09%09%09%7D
 %0A%09%09%09

Send behavior depends on message size