package fr.utbm.to52.smarthome.controller;

import java.io.IOException;
import java.util.Calendar;

import fr.utbm.to52.smarthome.events.AddRingEvent;
import fr.utbm.to52.smarthome.events.RingEvent;
import fr.utbm.to52.smarthome.model.Cron;
import fr.utbm.to52.smarthome.network.MQTT;
import fr.utbm.to52.smarthome.network.SocketInput;
import it.sauronsoftware.cron4j.ProcessTask;
import it.sauronsoftware.cron4j.SchedulingPattern;

/**
 * This controller is a singleton. For getting an instance from it 
 * <code>Controller.getInstance()</code> This initialize it with 
 * the default configuration file if it was not created before.
 * 
 * @author Alexandre Guyon
 *
 */
public class Controller {
	
	/**
	 * Singleton instance for this controller 
	 */
	private static Controller singleton = null;
	
	/**
	 * Get an instance from the controller. The first call initialize it with the default configuration file.
	 * @return Singleton instance of this controller
	 */
	public static Controller getInstance(){
		if(singleton == null)
			singleton = new Controller();
		return singleton;
	}
	
	private SocketInput server;
	private Thread mainThread;
	
	private MQTT mqtt;
	
	private Conf config;
	
	private Cron cron;
	
	private CommandHandlerImpl cmdHandler;
	
	private Controller(){
		this.config = new Conf();
		this.config.importConf();
		this.cmdHandler = new CommandHandlerImpl();
		this.mqtt = new MQTT(this.config.getMQTTID(), this.config.getMQTTServer(), this.config.getMQTTQOS(), this.cmdHandler);
	}

	/**
	 * Start the server
	 */
	public void start(){
		this.cron = new Cron();
		this.mqtt.connect();

		this.cmdHandler.setRingEventController(new RingEvent(this.mqtt));
		this.cmdHandler.setAddRingEventController(new AddRingEvent());
		
		try {
			this.server = new SocketInput(this.getConfig().getServerPort());
			this.server.setCmdHandler(this.cmdHandler);
			
			this.mainThread = new Thread(this.server);
			this.mainThread.start();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		this.stop();
	}
	
	/**
	 * Stop the server
	 */
	public void stopServer(){
		this.server.setRunning(false);
	}
	
	/**
	 * Stop the controller and so the app
	 */
	public void stop(){
		try {
			this.mainThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		this.mqtt.disconnect();
	}
	
	/**
	 * Add ring in the crontab with the corresponding date
	 * @param c The date to ring
	 */
	public void addRing(Calendar c){
		String[] broker = this.config.getMQTTServer().split(":");
		ProcessTask p = new ProcessTask("echo Ring | nc " + broker[1].substring(2) + " " + broker[2] + " #smart");
		
		int min = c.get(Calendar.MINUTE);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int d = c.get(Calendar.DAY_OF_MONTH);
		int m = c.get(Calendar.MONTH) + 1;
		
		this.cron.add(new SchedulingPattern(min +" " + hour + " " + d + " " + m + " *" ), p);
		
		this.cron.apply();
	}
	
	/**
	 * Get the configuration of the application loaded
	 * @return The configuration loaded.
	 */
	public Conf getConfig() {
		return this.config;
	}

	/**
	 * Set to the controller a special configuration
	 * @param config The configuration to set to the controller.
	 */
	public void setConfig(Conf config) {
		this.config = config;
	}
}

@@ -64,24 +64,46 @@
 Exception;%0D%0A
+import java.net.URL;%0D%0A
 import java.
@@ -458,16 +458,108 @@
 attern;%0D
+%0Aimport net.fortuna.ical4j.data.ParserException;%0D%0Aimport net.fortuna.ical4j.util.Calendars;%0D
 %0A%0D%0A/**%0D%0A
@@ -1754,24 +1754,28 @@
 ew Cron();%0D%0A
+%09%09%0D%0A
 %09%09this.mqtt.
@@ -2003,17 +2003,16 @@
 Port());
-%0D
 %0A%09%09%09this
@@ -2046,25 +2046,24 @@
 cmdHandler);
-%0D
 %0A%09%09%09%0D%0A%09%09%09thi
@@ -2211,22 +2211,352 @@
 his.
-stop();%0D%0A%09%7D%0D%0A%09
+loadICal();%0D%0A%09%09%0D%0A%09%09this.stop();%0D%0A%09%7D%0D%0A%09%0D%0A%09private void loadICal() %7B%0D%0A%09%09try %7B%0D%0A%09%09%09net.fortuna.ical4j.model.Calendar ical = Calendars.load(new URL(%22https://www.google.com/calendar/ical/alex.guyon78%2540gmail.com/private-c99c6c281cf94c48e85f2155434f0423/basic.ics%22));%0D%0A%09%09%7D catch (IOException %7C ParserException e) %7B%0D%0A%09%09%09e.printStackTrace();%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A
 %0D%0A%09/

resolve conflict add added base for ical