/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package malik.emulator.midp.protocol.sms;

import java.util.*;
import javax.wireless.messaging.*;
import malik.emulator.io.j2me.*;
import malik.emulator.midp.protocol.*;

final class MessageDeliveryEvent extends Object
		implements Runnable
{
	private static final String LOCAL_HOST_SMS_ADDRESS = "sms://:" +
			SupportedConnections.DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES;

	private static void pushReceivedMessage(ServerMessageConnection recipient,
			Message receivedMessage)
	{
		MessageListener listener;
		QueueOfObjects messagesQueue;
		synchronized(messagesQueue = recipient.incomingMessages)
		{
			messagesQueue.push(receivedMessage);
			messagesQueue.notify();
		}
		if((listener = recipient.listener) != null)
		{
			listener.notifyIncomingMessage(recipient);
		}
	}

	private static ServerMessageConnection getRecipient(String url)
	{
		int remotePort;
		String protocol;
		String remoteHost;
		URLParser urlParser;
		InboundConnection connection;
		ServerMessageConnection result;
		VirtualConnectionFactory factory = ImplementationManager.getConnectionFactory();
		if(url == null)
		{
			return (ServerMessageConnection) factory.getInboundConnection("sms",
					SupportedConnections.DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES);
		}
		try
		{
			(urlParser = new URLParser()).parse(url);
			protocol = urlParser.getProtocol();
			remoteHost = urlParser.getHostName();
			remotePort = urlParser.getPort();
			result = (ServerMessageConnection) (
					(protocol != null && "sms".equalsIgnoreCase(protocol)) &&
					(remoteHost == null || remoteHost.length() <= 0) &&
					(remotePort >= 0x0000 && remotePort <= 0xffff) &&
					(connection = factory.getInboundConnection("sms", remotePort)) instanceof
					ServerMessageConnection ? connection : factory.getInboundConnection("sms",
							SupportedConnections.DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES));
		}
		catch(RuntimeException e)
		{
			e.printRealStackTrace();
			result = (ServerMessageConnection) factory.getInboundConnection("sms",
					SupportedConnections.DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES);
		}
		return result;
	}

	private static Message createReceivedMessage(Message sentMessage)
	{
		if(sentMessage instanceof BinaryMessage)
		{
			return new MessageOfBytes(LOCAL_HOST_SMS_ADDRESS,
					((BinaryMessage) sentMessage).getPayloadData());
		}
		if(sentMessage instanceof TextMessage)
		{
			return new MessageOfChars(LOCAL_HOST_SMS_ADDRESS,
					((TextMessage) sentMessage).getPayloadText());
		}
		return null;
	}

	private static Message extractSentMessage(ClientMessageConnection sender)
	{
		Message result;
		QueueOfObjects messagesQueue;
		if((messagesQueue = sender.outgoingMessages).isEmpty())
		{
			return null;
		}
		synchronized(messagesQueue)
		{
			result = (Message) messagesQueue.peek();
			messagesQueue.removeTailElement();
		}
		return result;
	}


	private ClientMessageConnection sender;

	MessageDeliveryEvent(ClientMessageConnection sender)
	{
		this.sender = sender;
	}

	public void run()
	{
		Message sentMessage;
		Message receivedMessage;
		if((sentMessage = extractSentMessage(sender)) == null)
		{
			System.err.println("MessageConnection: нет исходящих сообщений.");
			return;
		}
		if((receivedMessage = createReceivedMessage(sentMessage)) == null)
		{
			System.err.println("MessageConnection: не удалось создать сообщение для получателя.");
			return;
		}
		pushReceivedMessage(getRecipient(sentMessage.getAddress()), receivedMessage);
	}
}
