/*
 *                                                                            
 *  Copyright (c) 2011 - 2016 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.abstractstatemachine;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.channels.SelectableChannel;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.PreDestroy;
import javax.swing.Timer;

import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.filter.IQuery;
import org.eclipse.osbp.runtime.common.session.ISession;
import org.eclipse.osbp.ui.api.customfields.IBlobService;
import org.eclipse.osbp.ui.api.message.IMessageRequester;
import org.eclipse.osbp.ui.api.message.MessageEvent;
import org.eclipse.osbp.ui.api.message.MessageEvent.EventType;
import org.eclipse.osbp.ui.api.message.MessageRequesterEvent;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.statemachine.IDataProvider;
import org.eclipse.osbp.ui.api.statemachine.IEventSource;
import org.eclipse.osbp.ui.api.statemachine.IPeripheral;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.utils.vaadin.MessageDialog;
import org.eclipse.osbp.utils.vaadin.YesNoDialog;
import org.eclipse.osbp.vaadin.addons.keyevents.KeyEventExtension;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.slf4j.Logger;

import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.server.Page;
import com.vaadin.server.WebBrowser;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

public abstract class AbstractStateMachine implements IStateMachine, IMessageRequester.ClickRecipient {
	private static final String ENABLED = "Enabled";
	private static Logger logger = org.slf4j.LoggerFactory.getLogger("statemachine");
	protected Collection<IEventSource.Enabler> enablerList = new CopyOnWriteArraySet<>();
	protected Collection<IDataProvider.Provider> providerList = new CopyOnWriteArraySet<>();
	protected Collection<IPeripheral.Command> peripheralList = new CopyOnWriteArraySet<>();
	protected Map<String, MessageDialog> messageDialogs = new HashMap<>();
	protected Map<String, YesNoDialog> yesnoDialogs = new HashMap<>();
	protected WebBrowser webBrowser = Page.getCurrent().getWebBrowser();
	protected IUser user;
	protected Locale locale;
	protected IDSLMetadataService dslMetadataService;
	protected IThemeResourceService themeResourceService;
	protected IReportProvider reportProvider;
	protected IBlobService blobService;
	protected Map<String, Map<String, Object>> storage = new HashMap<>();
	protected SelectableChannel channel;
	protected String lastTrigger;
	protected IEclipseContext eclipseContext;
	protected LinkedBlockingQueue<MessageEvent> queue = new LinkedBlockingQueue<>();
	protected boolean remotePortOverridden = false;

	protected Map<Integer, String> keyMapper = new HashMap<Integer, String>() {
		private static final long serialVersionUID = 8801421284339992078L;
		{
			put(KeyCode.TAB, "TAB");
			put(KeyCode.ENTER, "ENTER");
			put(KeyCode.ESCAPE, "ESC");
			put(KeyCode.PAGE_UP, "PGUP");
			put(KeyCode.PAGE_DOWN, "PGDOWN");
			put(KeyCode.F1, "F1");
			put(KeyCode.F2, "F2");
			put(KeyCode.F3, "F3");
			put(KeyCode.F4, "F4");
			put(KeyCode.F5, "F5");
			put(KeyCode.F6, "F6");
			put(KeyCode.F7, "F7");
			put(KeyCode.F8, "F8");
			put(KeyCode.F9, "F9");
			put(KeyCode.F10, "F10");
			put(KeyCode.F11, "F11");
			put(KeyCode.F12, "F12");
		}
	};
	private KeyEventExtension extension = null;
	private AtomicBoolean active = new AtomicBoolean(false);
	private AtomicBoolean blocking = new AtomicBoolean(false);
	private int remotePort = 9090;

	@Override
	public void installKeyEventConsumer(VerticalLayout layout) {
		extension = KeyEventExtension.addTo(layout);
		extension.setCallback(this::keyPressed);
	}

	@Override
	public void uninstallKeyEventConsumer() {
		if (extension != null) {
			extension.remove();
			extension = null;
		}
	}

	protected Component findById(HasComponents root, String id) {
		Iterator<Component> iterate = root.iterator();
		while (iterate.hasNext()) {
			Component c = iterate.next();
			if (id.equals(c.getId())) {
				return c;
			}
			if (c instanceof HasComponents) {
				Component cc = findById((HasComponents) c, id);
				if (cc != null)
					return cc;
			}
		}
		return null;
	}

	protected void keyPressed(org.eclipse.osbp.vaadin.addons.keyevents.client.Event e) {
		if (keyMapper.containsKey(e.charCode)) {
			logger.debug("keymapper code {}", keyMapper.get(e.charCode));
			processEvent(this, new MessageEvent(EventType.FUNCTIONALKEYBOARD, keyMapper.get(e.charCode)));
		} else {
			if(e.charCode > 95 && e.charCode < 106 ) {
				e.charCode -= 48;
			} else if(!e.shiftKeyDown && e.charCode > 57 && e.charCode < 91) {
				e.charCode += 32; 
			} else if(e.shiftKeyDown && e.charCode > 47 && e.charCode < 58) {
				e.charCode -= 16; 
			} else if(e.charCode == 192) {	// ö
				if(e.shiftKeyDown) {
					e.charCode = 0xD6;
				} else {
					e.charCode = 0xF6;
				}
			} else if(e.charCode == 222) {	// ä
				if(e.shiftKeyDown) {
					e.charCode = 0xC4;
				} else {
					e.charCode = 0xE4;
				}
			} else if(e.charCode == 186) {	// ü
				if(e.shiftKeyDown) {
					e.charCode = 0xDC;
				} else {
					e.charCode = 0xFC;
				}
			} else if(e.charCode == 219) {	// ß
				if(e.shiftKeyDown) {
					e.charCode = 63;
				} else {
					e.charCode = 0xDF;
				}
			}
			if (Character.isLetterOrDigit(e.charCode) || Character.isSpace((char)e.charCode)) {
				String evtCode = Character.toString((char) e.charCode);
				logger.debug("alpha or digit {}", evtCode);
				processEvent(this, new MessageEvent(EventType.KEYBOARD, Character.toString((char) e.charCode)));
			}
		}
	}

	public void processEvent(final IStateMachine statemachine, final MessageEvent event) {
		synchronized (queue) {
			logger.debug("enqueue event {}", event);
			queue.add(event);
		}
	}

	protected abstract void doProcessEvent(final IStateMachine statemachine, final MessageEvent event);

	private void addEventProvider(IEventSource.Enabler listener) {
		enablerList.add(listener);
	}

	private void removeEventProvider(IEventSource.Enabler listener) {
		enablerList.remove(listener);
	}

	@Override
	public void registerEnabler(IEventSource.Enabler listener) {
		addEventProvider(listener);
	}

	@Override
	public void unregisterEnabler(IEventSource.Enabler listener) {
		removeEventProvider(listener);
	}

	@Override
	public void setUser(IUser user) {
		this.user = user;
	}

	@Override
	public IUser getUser() {
		return user;
	}

	@Override
	public String getUserName() {
		return user.getUserName();
	}

	@Override
	public String getUserPassword() {
		return user.getExtraPassword();
	}

	@Override
	public String getUserEmail() {
		return user.getEmail();
	}

	@Override
	public String getUserPosition() {
		return user.getPosition();
	}

	@Override
	public String getUserPrintService() {
		return user.getPrintService();
	}

	@Override
	public void setLocale(Locale locale) {
		this.locale = locale;
	}

	@Override
	public Locale getLocale() {
		return locale;
	}

	@Override
	public void setDslMetadataService(IDSLMetadataService dslMetadataService) {
		this.dslMetadataService = dslMetadataService;
	}

	@Override
	public IDSLMetadataService getDslMetadataService() {
		return dslMetadataService;
	}

	@Override
	public IThemeResourceService getThemeResourceService() {
		return themeResourceService;
	}

	@Override
	public void setThemeResourceService(IThemeResourceService themeResourceService) {
		this.themeResourceService = themeResourceService;
	}

	@Override
	public void setReportProvider(IReportProvider reportprovider) {
		this.reportProvider = reportprovider;
	}

	@Override
	public IReportProvider getReportProvider() {
		return reportProvider;
	}

	@Override
	public IBlobService getBlobService() {
		return blobService;
	}

	@Override
	public void setBlobService(IBlobService blobService) {
		this.blobService = blobService;
	}

	@Override
	public void enable(String id, Boolean enable) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.enable(listener, id, enable);
		}
	}

	@Override
	public void toggle(String id) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.toggle(listener, id + ENABLED);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.toggle(listener, id + ENABLED);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.toggle(listener, id + ENABLED);
		}
	}

	@Override
	public Object get(String id) {
		Object value;
		for (IEventSource.Enabler listener : enablerList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		for (IDataProvider.Provider listener : providerList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		for (IPeripheral.Command listener : peripheralList) {
			value = listener.get(listener, id);
			if (value != null) {
				return value;
			}
		}
		return null;
	}

	@Override
	public void set(String id, Object content) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.set(listener, id, content);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.set(listener, id, content);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.set(listener, id, content);
		}
	}

	@Override
	public void set(String id, String device, Object content) {
		for (IPeripheral.Command listener : peripheralList) {
			listener.set(listener, id, device, content);
		}
	}

	@Override
	public void clear(String id) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.clear(listener, id);
		}
		for (IDataProvider.Provider listener : providerList) {
			listener.clear(listener, id);
		}
		for (IPeripheral.Command listener : peripheralList) {
			listener.clear(listener, id);
		}
	}

	@Override
	public void append(String id, String key) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.append(listener, id, key);
		}
	}

	@Override
	public void remove(String id, int pos) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.remove(listener, id, pos);
		}
	}

	@Override
	public void caption(String id, String value) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.caption(listener, id, value);
		}
	}

	@Override
	public void image(String id, String imageName) {
		for (IEventSource.Enabler listener : enablerList) {
			listener.image(listener, id, imageName);
		}
	}

	@Override
	public void addDataProvider(IDataProvider.Provider listener) {
		providerList.add(listener);
	}

	@Override
	public void removeDataProvider(IDataProvider.Provider listener) {
		providerList.remove(listener);
	}

	@Override
	public void registerDataProvider(IDataProvider.Provider listener) {
		addDataProvider(listener);
	}

	@Override
	public void unregisterDataProvider(IDataProvider.Provider listener) {
		removeDataProvider(listener);
	}

	public void addPeripheral(IPeripheral.Command listener) {
		peripheralList.add(listener);
	}

	public void removePeripheral(IPeripheral.Command listener) {
		peripheralList.remove(listener);
	}

	@Override
	public void registerPeripheral(IPeripheral.Command listener) {
		addPeripheral(listener);
	}

	@Override
	public void unregisterPeripheral(IPeripheral.Command listener) {
		removePeripheral(listener);
	}

	@Override
	public Boolean find(String dtoName, IQuery query) {
		Boolean retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.find(listener, dtoName, query);
			if (retVal != null) {
				return retVal;
			}
		}
		return false;
	}

	@Override
	public Boolean find(String dtoName, String fieldName, Object search) {
		Boolean retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.find(listener, dtoName, fieldName, search);
			if (retVal != null) {
				return retVal;
			}
		}
		return false;
	}

	@Override
	public Collection<? extends IDto> findAll(String dtoName, IQuery query) {
		Collection<? extends IDto> retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.findAll(dtoName, query);
			if (retVal != null) {
				return retVal;
			}
		}
		return Collections.emptyList();
	}

	@Override
	public Collection<? extends IDto> findAll(String dtoName, String fieldName, Object search) {
		Collection<? extends IDto> retVal;
		for (IDataProvider.Provider listener : providerList) {
			retVal = listener.findAll(dtoName, fieldName, search);
			if (retVal != null) {
				return retVal;
			}
		}
		return Collections.emptyList();
	}

	@Override
	public void addTo(String dtoName, String listName, IDto dto) {
		for (IDataProvider.Provider listener : providerList) {
			listener.addTo(listener, dtoName, listName, dto);
		}
	}

	@Override
	public void removeFrom(String dtoName, String listName, IDto dto) {
		for (IDataProvider.Provider listener : providerList) {
			listener.removeFrom(listener, dtoName, listName, dto);
		}
	}

	@Override
	public void update(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.update(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public void reload(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.reload(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public void delete(String dtoName) {
		for (IDataProvider.Provider listener : providerList) {
			listener.delete(listener, dtoName, (IDto) listener.get(listener, dtoName));
		}
	}

	@Override
	public String getIPAddress() {
		// must define -Djava.net.preferIPv4Stack=true to always get IPv4 in
		// dual stack environments
		return webBrowser.getAddress(); // May be null, especially if running in
										// a Portlet.
	}

	@Override
	public String getHostName() {
		String hostName = null;
		try {
			InetAddress netAddress = InetAddress.getByName(webBrowser.getAddress());
			hostName = netAddress.getHostName().toLowerCase();
			logger.error("**** browser returned this host-name: {} ****", hostName);
		} catch (UnknownHostException e) {
			logger.error("{}", e);
		}
		return hostName;
	}
	
	@Override
	public int getRemotePort() {
		if(!remotePortOverridden) {
			if(ProductConfiguration.getJavaPosPortConfiguration() != null) {
				return Integer.parseInt(ProductConfiguration.getJavaPosPortConfiguration());
			}
		}
		return remotePort;
	}
	
	@Override
	public void setRemotePort(int port) {
		remotePortOverridden = true;
		this.remotePort = remotePort;
	}

	@Override
	public boolean isItMe(String hostName) {
		String hostAddress;
		try {
			InetAddress netAddress = InetAddress.getByName(hostName);
			hostAddress = netAddress.getHostAddress();
			logger.error("**** browser returned this host-address: {} ****", hostAddress);
		} catch (UnknownHostException e) {
			logger.error("{}", e);
			return false;
		}
		boolean ret = getIPAddress().equals(hostAddress);
		if(!ret) {
			logger.error("**** browser host-address and requested host are not equal! Requested: {} ****", hostName);
		}
		return ret;
	}

	@Override
	public DateTime getNow() {
		return DateTime.now(DateTimeZone.UTC);
	}

	@Override
	public String getUserAgentInfo() {
		return webBrowser.getBrowserApplication();
	}

	@Override
	public Boolean isTouchDevice() {
		return webBrowser.isTouchDevice();
	}

	@Override
	public int getSceenWidth() {
		return webBrowser.getScreenWidth();
	}

	@Override
	public int getScreenHeight() {
		return webBrowser.getScreenHeight();
	}

	@PreDestroy
	void destroy() {
	}

	@Override
	public Locale getBrowserLocale() {
		return webBrowser.getLocale();
	}

	@Override
	public Boolean isHttps() {
		return webBrowser.isSecureConnection();
	}

	public void start() {
		active.set(true);
		final UI ui = getEclipseContext().get(UI.class);
		Runnable runnable = () -> {
			while (active.get()) {
				if(!blocking.get()) {
					MessageEvent event;
					try {
						event = queue.take();
						ui.access(() -> {
							logger.debug("doProcess event {}", event);
							doProcessEvent(AbstractStateMachine.this, event);
						});
					} catch (InterruptedException e) {
						logger.debug("dequeuing was interrupted {}", e);
						Thread.currentThread().interrupt();
					}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					// TODO sleep interrupted
				}
			}
		};

		Thread thread = new Thread(runnable, "Statemachine processor " + getClass().getName());
		thread.setDaemon(true);
		thread.start();
	}

	@Override
	public void schedule(IStateMachine statemachine, int milliseconds, MessageEvent event) {
		Timer timer = new Timer(milliseconds, action -> statemachine.processEvent(statemachine, event));
		timer.setRepeats(false);
		timer.start();
	}

	/**
	 * @param doubleStr
	 * @return Double independent of locale
	 */
	@Override
	public Double parseDouble(String doubleStr) {
		String doubleStrIn = doubleStr.replaceAll("[^\\d,\\.]++", "");
		if (doubleStrIn.length() == 0) {
			return 0.0;
		}
		if (doubleStrIn.matches(".+\\.\\d+,\\d+$"))
			return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", "."));
		if (doubleStrIn.matches(".+,\\d+\\.\\d+$"))
			return Double.parseDouble(doubleStrIn.replaceAll(",", ""));
		return Double.parseDouble(doubleStrIn.replaceAll(",", "."));
	}

	/**
	 * Format a double.
	 *
	 * @param value
	 *            the value
	 * @param length
	 *            the total length of the resulting string
	 * @param precision
	 *            the precision after decimal separator
	 * @return the string
	 */
	@Override
	public String formatDouble(Double value, int length, int precision) {
		String format = String.format("%% %d.%df", length, precision);
		return String.format(locale, format, value);
	}

	@Override
	public String getTranslation(String token) {
		if (dslMetadataService != null && locale != null) {
			return dslMetadataService.translate(locale.toLanguageTag(), token);
		}
		return token;
	}

	@Override
	public void closeMessage(String messageId) {
		if (messageDialogs.containsKey(messageId)) {
			MessageDialog messageDialog = messageDialogs.get(messageId);
			messageDialog.close();
			UI.getCurrent().removeWindow(messageDialog);
			messageDialogs.remove(messageId);
		}
	}

	@Override
	public void openMessage(String messageId) {
		openMessage(messageId, false);
	}

	@Override
	public void openMessage(String messageId, boolean okButton) {
		MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId));
		if (okButton) {
			messageDialog.addButton(getTranslation("ok"), new MessageEvent(EventType.MESSAGECLOSE, messageId));
			messageDialog.addButtonListener(this);
		}
		messageDialogs.put(messageId, messageDialog);
		UI.getCurrent().addWindow(messageDialog);
	}

	@Override
	public void openQuestion(String messageId, EventType type, String yesEvent, String noEvent, String cancelEvent) {
		MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId));
		messageDialog.addButton(getTranslation("yes"), new MessageEvent(type, yesEvent));
		messageDialog.addButton(getTranslation("no"), new MessageEvent(type, noEvent));
		messageDialog.addButton(getTranslation("cancel"), new MessageEvent(type, cancelEvent));
		messageDialog.addButtonListener(this);
		messageDialogs.put(messageId, messageDialog);
		UI.getCurrent().addWindow(messageDialog);
	}

	@Override
	public void messageButtonPressed(MessageRequesterEvent e) {
		MessageDialog messageDialog = messageDialogs.get(e.getId());
		messageDialog.close();
		UI.getCurrent().removeWindow(messageDialog);
		messageDialogs.remove(e.getId());
		this.processEvent(this, e.getEventData());
	}

	@Override
	public void dispatchMessages(MessageEvent event) {
		if (event.getType() == MessageEvent.EventType.TRIGGER) {
			lastTrigger = event.getId();
		}
		switch (event.getType()) {
		case ERROR:
			openMessage(event.getId(), true);
			break;
		case MESSAGEOPEN:
			openMessage(event.getId());
			break;
		case MESSAGECLOSE:
			closeMessage(event.getId());
			break;
		case STATUSOPEN:
		case STATUSCLOSE:
		default:
			break;
		}
	}

	@Override
	public Object getStorage(String key, String attribute) {
		if (storage.containsKey(key) && storage.get(key).containsKey(attribute)) {
			return storage.get(key).get(attribute);
		}
		return null;
	}

	@Override
	public Set<String> getStorageAttributes(String key) {
		if (storage.containsKey(key)) {
			return storage.get(key).keySet();
		}
		return Collections.emptySet();
	}

	@Override
	public void putStorage(String key, String attribute, Object content) {
		if (!storage.containsKey(key)) {
			storage.put(key, new HashMap<String, Object>());
		}
		storage.get(key).put(attribute, content);
	}

	@Override
	public void openChannel(SelectableChannel channel) {
		this.channel = channel;
	}

	@Override
	public SelectableChannel getChannel() {
		return channel;
	}

	@Override
	public void closeChannel() {
		if (channel != null) {
			try {
				channel.close();
			} catch (IOException e) { // NOSONAR
				// do nothing
			}
		}
	}

	@Override
	public String getLastTrigger() {
		return lastTrigger;
	}

	@Override
	public void setEclipseContext(IEclipseContext eclipseContext) {
		this.eclipseContext = eclipseContext;
		this.dslMetadataService = eclipseContext.get(IDSLMetadataService.class);
		this.themeResourceService = eclipseContext.get(IThemeResourceService.class);
		this.reportProvider = eclipseContext.get(IReportProvider.class);
		this.blobService = eclipseContext.get(IBlobService.class);
	}

	@Override
	public IEclipseContext getEclipseContext() {
		return eclipseContext;
	}

	@Override
	public void sendSlaveData(Map<String, Object> data) {
		String currentInstanceId = (String) getEclipseContext().get("e4ApplicationInstanceId");
		List<ISession> sessions = POSServiceBinder.getSessionManager()
				.getSessions(s -> s.get("e4ApplicationInstanceId").equals(currentInstanceId));
		if (!sessions.isEmpty()) {
			List<ISession> slaves = sessions.get(0).getSlaves();
			for (ISession slave : slaves) {
				slave.async(e -> {
					slave.sendData(data);
					return true;
				}, null);
			}
		}
	}
	
	@Override
	public void blockQueueTaking(boolean block) {
		logger.debug("switch blocking {}", block);
		blocking.set(block);
	}
	
	@Override
	public boolean isJavaPosRemote() {
		String cmd = String.format("http://%s:%d/devices/posParameters", getHostName(), getRemotePort());
		HttpGet get = new HttpGet(cmd);
		get.addHeader("Accept", "application/json");
		
		try(CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
			CloseableHttpResponse response = httpClient.execute(get);
			logger.info(EntityUtils.toString(response.getEntity()));
			return true;
		} catch (ParseException | IOException e) {
			// it's ok - we have no remote javapos
		} finally {
			get.releaseConnection();
		}
		return false;
	}
}
