package floor;

import java.io.IOException;
import java.util.logging.Logger;

import common.AbstractReceiver;
import common.LoggerUtil;
import communication.MessageUtil;
import communication.Port;
import communication.messages.FloorArrivalMessage;
import communication.messages.InitializeMessage;
import communication.messages.Message;
import communication.messages.StartEventsMessage;
import error.ExceptionUtil;
import error.InputFormatException;
import error.UnexpectedMessageTypeException;
import floor.input.InputParser;

/**
 * Class to handle receiving of messages for the floor subsystem
 */
public class FloorReceiver extends AbstractReceiver {
	private static final Logger logger = LoggerUtil.getLoggerForClass(FloorReceiver.class);
	private final FloorSubsystem floorSubsystem;

	/**
	 * Create new floor receiver
	 *
	 * @throws IOException
	 */
	public FloorReceiver() throws IOException {
		super(Port.FLOOR);
		floorSubsystem = new FloorSubsystem();
	}

	@Override
	public void handleMessage(Message msg) {
		try {
			if (msg instanceof FloorArrivalMessage) {
				floorSubsystem.handleMessage((FloorArrivalMessage) msg);
			} else if (msg instanceof InitializeMessage) {
				logger.config("Received initialize message from Scheduler");
				floorSubsystem.initializeSystem((InitializeMessage) msg);
			} else if (msg instanceof StartEventsMessage) {
				logger.config("Received start events message from Scheduler");
				InputParser.setupInputs(floorSubsystem);
			} else {
				ExceptionUtil.handleRecoverableException(new UnexpectedMessageTypeException(),
						"Received a message not meant for this subsystem", logger);
			}
		} catch (IOException e) {
			ExceptionUtil.handleRecoverableException(e, "Could not convert packet to message", logger);
		} catch (InputFormatException e) {
			ExceptionUtil.handleCriticalException(e, "Exception occured while parsing simulated input messages",
					logger);
		}
	}

	public static void main(String[] args) {
		MessageUtil.setIPAddress(Port.SCHEDULER, args, 0);

		try {
			new FloorReceiver().receiveAndHandlePackets(logger);
		} catch (IOException e) {
			ExceptionUtil.handleCriticalException(e, "An IO Exception occured while operating floor receiver", logger);
		}
	}
}
