/**
 * Copyright (c) 2018 CEA.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     CEA - initial API and implementation and/or initial documentation
 */
package org.eclipse.sensinact.studio.model.manager.modelupdater;

import java.io.IOException;
import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
import org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated.MsgAttributeValueUpdated;
import org.eclipse.sensinact.studio.http.messages.snamessage.basic.MsgHttpError;
import org.eclipse.sensinact.studio.http.messages.snamessage.completelist.MsgCompleteList;
import org.eclipse.sensinact.studio.http.messages.snamessage.completelist.ObjectProvider;
import org.eclipse.sensinact.studio.http.messages.snamessage.getresponse.MsgGetResponse;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgProviderAppearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgProviderDisappearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgResourceAppearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgResourceDisappearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgServiceAppearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgServiceDisappearing;
import org.eclipse.sensinact.studio.http.messages.snamessage.resourceslist.MsgResourcesList;
import org.eclipse.sensinact.studio.http.messages.snamessage.serviceslist.MsgServicesList;
import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient.RequestParameter;
import org.eclipse.sensinact.studio.http.services.client.connectionmanager.NotifDispatcher;
import org.eclipse.sensinact.studio.http.services.client.listener.NotifSubscriptionListener;
import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
import org.eclipse.sensinact.studio.model.resource.utils.Segments;
import org.eclipse.sensinact.studio.model.resource.utils.ServiceDescriptor;
import org.eclipse.sensinact.studio.resource.AccessMethodType;

/**
 * @author Nicolas Hili, Etienne Gandrille, Jander and others
 */
public class ModelUpdater implements NotifSubscriptionListener {

	private static final Logger logger = Logger.getLogger(ModelUpdater.class);
	
	private static ModelUpdater INSTANCE;
	
	public static ModelUpdater getInstance() {
		if (INSTANCE == null)
			INSTANCE = new ModelUpdater();
		return INSTANCE;
	}


	private final ModelUpdateStack stack = new ModelUpdateStack();
	
	private ModelUpdater() {
		NotifDispatcher.getInstance().subscribe(this);
	}

	/**
	 * Get all devices from the gateway and updates the model.
	 * 
	 * @throws IOException
	 */
	public void updateDevices(final String gatewayName) throws IOException {
		
			logger.info("Full model update triggered");

			Segments segments = new Segments.Builder().gateway(gatewayName).root().build();
			MsgSensinact snaMsg = GatewayHttpClient.sendGetRequest(segments);
			
			if (!(snaMsg instanceof MsgCompleteList)) {
				displayLogOnError(snaMsg, "devices");
				return;
			}

			MsgCompleteList list = (MsgCompleteList) snaMsg;
			
			// update devices list
			new Thread() {
				public void run() {
					// remove device
					for (String localDeviceId : ModelEditor.getInstance().getDevicesId(gatewayName)) {	
						try {
							if(!list.getProvidersId().contains(localDeviceId))
								stack.add(new DeviceDisappearing(new DeviceDescriptor(gatewayName, localDeviceId)));							
						}catch(Exception e) {
							logger.error(e.getMessage(),e);							
						}
					}
					// add devices						
					for (ObjectProvider provider : list.getProviders()){
						if(provider.getLocation() == null){
							continue;
						}
						DeviceDescriptor desc = new DeviceDescriptor(gatewayName, provider.getName());
						desc.setLocation(provider.getLocation());
						stack.add(new DeviceAppearing(desc));
					}
				}
			}.start();
	}

	/**
	 * Get all services on a device, from the gateway, and updates the model.
	 * 
	 * @param device
	 *            the device from which services need to be retrieved
	 * @throws IOException
	 */
	public void updateServices(final String gatewayName, final String deviceId) throws IOException {
		
		Segments segments = new Segments.Builder().gateway(gatewayName).device(deviceId).services().build();		
		MsgSensinact snaMsg = GatewayHttpClient.sendGetRequest(segments);
		
		if (!(snaMsg instanceof MsgServicesList)) {
			System.out.println(snaMsg);
			displayLogOnError(snaMsg, "services");
			return;
		}
		if(((MsgServicesList) snaMsg).getServices() == null)
			return;

		// remove service
		for (String localServiceId : ModelEditor.getInstance().getServicesId(gatewayName, deviceId)) {		
			try {		
				if(!((MsgServicesList) snaMsg).getServices().contains(localServiceId)) 
					stack.add(new ServiceDisappearing(new ServiceDescriptor(gatewayName, deviceId, localServiceId)));
			} catch(Exception ex) {
				logger.error(ex.getMessage(),ex);
			}
		}
		
		for (String service : ((MsgServicesList) snaMsg).getServices()){
			stack.add(new ServiceAppearing(new ServiceDescriptor(gatewayName, deviceId, service)));
		}
	}
	
	/* ================ */
	/* Update resources */
	/* ================ */
	
	/**
	 * Retrieve all resources from one service
	 * 
	 * @param service
	 *            the service from which resources need to be retrieved
	 * @throws IOException
	 */
	public void updateResources(final String gatewayName, final String deviceId, final String serviceId) throws IOException {
		Segments segment = new Segments.Builder().gateway(gatewayName).device(deviceId).service(serviceId).resources().build();

		MsgSensinact msg = GatewayHttpClient.sendGetRequest(segment);
		
		if (!(msg instanceof MsgResourcesList)) {
			displayLogOnError(msg, "resources");
			return;
		}			
		if(((MsgResourcesList) msg).getResources() == null)
			return;

		// remove resources
		for (String localResourceId : ModelEditor.getInstance().getResourcesId(gatewayName, deviceId, serviceId)) {		
			try {		
				if(!((MsgResourcesList) msg).getResources().contains(localResourceId)) 
					stack.add(new ResourceDisappearing(new ResourceDescriptor(gatewayName, deviceId, serviceId,localResourceId)));
			} catch(Exception ex) {
				logger.error(ex.getMessage(),ex);
			}
		}
		//add resources
		for (String resource : ((MsgResourcesList) msg).getResources()) {
			if(serviceId.equals("admin") && resource.equals("icon")) {
				try {
					ResourceDescriptor rd = updateResource(gatewayName, deviceId, serviceId, resource);
					if(rd != null) {
						stack.add(new ResourceAppearing(rd));
						String icon = null;
						ObjectNameTypeValue ontv = rd.getInitial();
						if(ontv != null) {
							String ic = ontv.getValueAsString();
							icon = "null".equals(ic)?null:ic;							
						}
						ModelEditor.getInstance().setIcon(new DeviceDescriptor(rd.getGateway(), rd.getDevice()), icon);
					}
				} catch(Exception ex) {
					logger.error(ex.getMessage(),ex);
				}
			} else
				stack.add(new ResourceAppearing(new ResourceDescriptor(gatewayName, deviceId, serviceId, resource)));
		}		
	}

	/**
	 * Retrieve all resources from one service
	 * 
	 * @param service
	 *            the service from which resources need to be retrieved
	 * @throws IOException
	 */
	public ResourceDescriptor updateResource(final String gatewayName, final String deviceId, final String serviceId, final String resourceId) throws IOException {
		Segments segment = new Segments.Builder().gateway(gatewayName).device(deviceId).service(serviceId).resource(resourceId).method(AccessMethodType.GET).build();
		MsgSensinact msg = GatewayHttpClient.sendGetRequest(segment);
		if (!(msg instanceof MsgGetResponse)) {
			displayLogOnError(msg, "GET");
			return null;
		}
		MsgGetResponse response  = (MsgGetResponse)msg;
		ResourceDescriptor desc = new ResourceDescriptor(gatewayName, deviceId, serviceId, resourceId);
		desc.setInitial(response.getResponse());
		return desc;	
	}
	
	/* =============== */
	/* Update location */
	/* =============== */

	public boolean updateLocationOnServer(DeviceDescriptor deviceDescriptor, GPScoordinates coordinates) {
		Segments segments = new Segments.Builder().device(deviceDescriptor).service("admin").resource("location").method(AccessMethodType.SET).build();
		RequestParameter param = new RequestParameter("location", "string", coordinates.getLat() + ":" + coordinates.getLng());
		try {
			MsgSensinact msg = GatewayHttpClient.sendPostRequest(segments, null,param);
			if (msg instanceof MsgHttpError) {
				return false;
			} else {
				return true;
			}
		} catch (IOException e) {
			logger.error("Update location on server failed", e);
			return false;
		}		
	}
	
	/* ========= */
	/* Listeners */
	/* ========= */
	
	@Override
	public void onLifecycleEvent(String gateway, List<MsgSensinact> messages) {
		for (MsgSensinact message : messages)
			onLifecycleEvent(gateway, message);
	}
	
	public void onLifecycleEvent(String gateway, MsgSensinact message) {
		
		String uri = message.getUri();
		ModelUpdate<?> mu = null;
		
		if (message instanceof MsgProviderAppearing) {
			mu = new DeviceAppearing(new DeviceDescriptor(gateway, getProviderName(uri)));
			
		} else if (message instanceof MsgProviderDisappearing) {
			mu = new DeviceDisappearing(new DeviceDescriptor(gateway, getProviderName(uri)));			
			
		} else if (message instanceof MsgServiceAppearing) {
			mu = new ServiceAppearing(new ServiceDescriptor(gateway, getProviderName(uri),getServiceName(uri)));
		
		} else if (message instanceof MsgServiceDisappearing) {
			mu = new ServiceDisappearing(new ServiceDescriptor(gateway, getProviderName(uri),getServiceName(uri)));
			
		} else if (message instanceof MsgResourceAppearing) {
			ResourceDescriptor d = new ResourceDescriptor(gateway,getProviderName(uri),getServiceName(uri),getResourceName(uri));
			d.setInitial(((MsgResourceAppearing)message).getInitial());
			mu = new ResourceAppearing(d);
			
		} else if (message instanceof MsgResourceDisappearing) {
			mu = new ResourceDisappearing(new ResourceDescriptor(gateway, 
					getProviderName(uri),getServiceName(uri),
					getResourceName(uri)));
		} else {
			displayLogOnError(message, "lifecycle");
			return;
		}
		stack.add(mu);
	}

	@Override
	public void onLocationEvent(String gateway, List<MsgSensinact> messages) {
		for (MsgSensinact message : messages)
			onLocationEvent(gateway, message);
	}
	
	public void onLocationEvent(String gateway, MsgSensinact message) {
	
		if(!(message instanceof MsgAttributeValueUpdated) || !((MsgAttributeValueUpdated)message).isLocationValue()){
			return;
		}
		MsgAttributeValueUpdated lu = (MsgAttributeValueUpdated)message;
		String uri = lu.getUri();
		String device = getProviderName(uri);
		try {
			lu.getUri();
			ModelEditor.getInstance().setLocation(new DeviceDescriptor(gateway, device), 
			new GPScoordinates(lu.getNotification().getValueAsString()));
			
		} catch (GPSparsingException e) {			
			logger.error(e.getMessage(),e);
		}
	}
	
	static void executeInThread(Runnable r){
		Runnable runnableWithTry = () -> {
			try {
				r.run();
			} catch (Exception e) {
				logger.error(e);
			}
		}; 		
		new Thread(runnableWithTry).start();
    }

	public void onIconEvent(String gateway, List<MsgSensinact> messages) {
		for (MsgSensinact message : messages)
			onIconEvent(gateway, message);
	}

	@Override
	public void onIconEvent(String gateway, MsgSensinact message) {
		if(!(message instanceof MsgAttributeValueUpdated) || !((MsgAttributeValueUpdated)message).isIconValue()){
			return;
		}
		MsgAttributeValueUpdated lu = (MsgAttributeValueUpdated)message;
		String uri = lu.getUri();
		String device = getProviderName(uri);
		ModelEditor.getInstance().setIcon(new DeviceDescriptor(gateway, device),  lu.getNotification().getValueAsString());
	}

	@Override
	public void onValueEvent(String gateway, List<MsgSensinact> messages) {
		// do nothing for now
		
	}
	
	private String getProviderName(String uri) {
		String[] tokens = uri.split("/");
		return tokens[1];
	}

	private String getServiceName(String uri) {
		String[] tokens = uri.split("/");
		return tokens[2];
	}
	
	private String getResourceName(String uri) {
		String[] tokens = uri.split("/");
		return tokens[3];
	}
	
	/* ========= */
	/* Exception */
	/* ========= */
	
	private void displayLogOnError(MsgSensinact response, String elementName) {
		String fullMsg = String.format("Error sent by gateway while getting %s (%s)", elementName, response.getType());
		logger.error(fullMsg);
	}
}
