/*******************************************************************************
 * Copyright (C) 2021 the Eclipse BaSyx Authors
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 ******************************************************************************/
package org.eclipse.basyx.vab.protocol.basyx.server;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;

import org.eclipse.basyx.vab.coder.json.provider.JSONProvider;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.modelprovider.api.IModelProvider;
import org.eclipse.basyx.vab.protocol.basyx.CoderTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provider class that enables access to an IModelProvider via native BaSyx
 * protocol
 * 
 * @author kuhn, pschorn
 *
 */
public class VABBaSyxTCPInterface<ModelProvider extends IModelProvider> extends Thread {

	private static Logger logger = LoggerFactory.getLogger(VABBaSyxTCPInterface.class);

	/**
	 * BaSyx get command
	 */
	public static final byte BASYX_GET = 0x01;

	/**
	 * BaSyx set command
	 */
	public static final byte BASYX_SET = 0x02;

	/**
	 * BaSyx create command
	 */
	public static final byte BASYX_CREATE = 0x03;

	/**
	 * BaSyx delete command
	 */
	public static final byte BASYX_DELETE = 0x04;

	/**
	 * BaSyx invoke command
	 */
	public static final byte BASYX_INVOKE = 0x05;

	/**
	 * BaSyx result 'OK' : 0x00
	 */
	public static final byte BASYX_RESULT_OK = 0x00;

	/**
	 * Reference to IModelProvider backend
	 */
	protected JSONProvider<ModelProvider> providerBackend = null;

	/**
	 * Socket communication channel
	 */
	protected SocketChannel commChannel = null;

	/**
	 * Constructor that accepts an already created server socket channel
	 */
	public VABBaSyxTCPInterface(ModelProvider modelProviderBackend, SocketChannel channel) {
		// Store reference to channel and backend
		providerBackend = new JSONProvider<ModelProvider>(modelProviderBackend);
		commChannel = channel;
		setName(VABBaSyxTCPInterface.class.getName() + " " + System.currentTimeMillis());
		logger.debug("Socket created");
	}

	/**
	 * Process input frame
	 */
	public void processInputFrame(byte[] rxFrame) throws IOException {
		// Create output streams
		ByteArrayOutputStream output = new ByteArrayOutputStream();

		// Get command
		switch (rxFrame[0]) {

		case BASYX_GET: {
			// Get path string
			int pathLen = CoderTools.getInt32(rxFrame, 1);
			String path = new String(rxFrame, 1 + 4, pathLen);

			// Forward request to provider
			try {
				providerBackend.processBaSysGet(path, output);
			} catch (ProviderException e) {
				logger.debug("Exception in BASYX_GET", e);
				// Catch Exceptions from JSONProvider
				// No further action here, as the current version
				// of the TCP-Mapping states, that always Statuscode 0x00 
				// should be returned with Exceptions encoded in returned String
			}

			// System.out.println("Processed GET:"+path);

			// Send response frame
			output.flush();
			sendResponseFrame(output);

			break;
		}

		case BASYX_SET: {
			// Get path string length and value
			int pathLen = CoderTools.getInt32(rxFrame, 1);
			String path = new String(rxFrame, 1 + 4, pathLen);
			// Get value string length and value
			int jsonValueLen = CoderTools.getInt32(rxFrame, 1 + 4 + pathLen);
			String jsonValue = new String(rxFrame, 1 + 4 + pathLen + 4, jsonValueLen);

			// Invoke get operation
			try {
				providerBackend.processBaSysSet(path, jsonValue, output);
			} catch (ProviderException e) {
				logger.debug("Exception in BASYX_SET", e);
				// Catch Exceptions from JSONProvider
				// No further action here, as the current version
				// of the TCP-Mapping states, that always Statuscode 0x00 
				// should be returned with Exceptions encoded in returned String
			}

			// Send response frame
			output.flush();
			sendResponseFrame(output);

			break;
		}

		case BASYX_CREATE: {
			// Get path string length and value
			int pathLen = CoderTools.getInt32(rxFrame, 1);
			String path = new String(rxFrame, 1 + 4, pathLen);
			// Get value string length and value
			int jsonValueLen = CoderTools.getInt32(rxFrame, 1 + 4 + pathLen);
			String jsonValue = new String(rxFrame, 1 + 4 + pathLen + 4, jsonValueLen);

			// Invoke get operation
			try {
				providerBackend.processBaSysCreate(path, jsonValue, output);
			} catch (ProviderException e) {
				logger.debug("Exception in BASYX_CREATE", e);
				// Catch Exceptions from JSONProvider
				// No further action here, as the current version
				// of the TCP-Mapping states, that always Statuscode 0x00 
				// should be returned with Exceptions encoded in returned String
			}

			// Send response frame
			output.flush();
			sendResponseFrame(output);

			break;
		}

		case BASYX_DELETE: {
			// Get path string length and value
			int pathLen = CoderTools.getInt32(rxFrame, 1);
			String path = new String(rxFrame, 1 + 4, pathLen);

			// Get value string length and value if available; default is null value
			String jsonValue = "";
			try {
				int jsonValueLen = CoderTools.getInt32(rxFrame, 1 + 4 + pathLen);
				jsonValue = new String(rxFrame, 1 + 4 + pathLen + 4, jsonValueLen);

			} catch (ArrayIndexOutOfBoundsException e) {
				// pass, provide serialize null argument to processBaSysDelete to indicate that
				// an
				// entity should be removed
			}

			// Invoke delete operation
			try {
				providerBackend.processBaSysDelete(path, jsonValue, output);
			} catch (ProviderException e) {
				logger.debug("Exception in BASYX_DELETE", e);
				// Catch Exceptions from JSONProvider
				// No further action here, as the current version
				// of the TCP-Mapping states, that always Statuscode 0x00 
				// should be returned with Exceptions encoded in returned String
			}

			// Send response frame
			output.flush();
			sendResponseFrame(output);

			break;
		}

		case BASYX_INVOKE: {
			// Get path string length and value
			int pathLen = CoderTools.getInt32(rxFrame, 1);
			String path = new String(rxFrame, 1 + 4, pathLen);
			// Get value string length and value
			int jsonValueLen = CoderTools.getInt32(rxFrame, 1 + 4 + pathLen);
			String jsonValue = new String(rxFrame, 1 + 4 + pathLen + 4, jsonValueLen);
			// Invoke get operation
			try {
				providerBackend.processBaSysInvoke(path, jsonValue, output);
			} catch (ProviderException e) {
				logger.debug("Exception in BASYX_INVOKE", e);
				// Catch Exceptions from JSONProvider
				// No further action here, as the current version
				// of the TCP-Mapping states, that always Statuscode 0x00 
				// should be returned with Exceptions encoded in returned String
			}

			// Send response frame
			output.flush();
			sendResponseFrame(output);

			break;
		}

		default:
			throw new RuntimeException("Unknown BaSyx TCP command received");
		}
	}

	/**
	 * Sends a response to the client that carries the JSON response
	 * 
	 * @param byteArrayOutput
	 * @throws IOException
	 */
	private void sendResponseFrame(ByteArrayOutputStream byteArrayOutput) throws IOException {
		// Create response frame with positive response
		sendResponseFrame(byteArrayOutput, BASYX_RESULT_OK);
	}

	/**
	 * Sends a response to the client that carries the JSON response
	 * 
	 * @param byteArrayOutput
	 * @throws IOException
	 */
	private void sendResponseFrame(ByteArrayOutputStream byteArrayOutput, int result) throws IOException {
		// Create response frame
		byte[] encodedResult = byteArrayOutput.toByteArray();
		int resultFrameSize = encodedResult.length + 1;
		byte[] frameLength = new byte[4];
		byte[] encodedResultLength = new byte[4];
		CoderTools.setInt32(frameLength, 0, resultFrameSize + 4);
		CoderTools.setInt32(encodedResultLength, 0, encodedResult.length);

		// Place response frame in buffer
		ByteBuffer buffer = ByteBuffer.allocate(resultFrameSize + 4 + 4);
		buffer.put(frameLength);
		buffer.put((byte) result);
		buffer.put(encodedResultLength);
		buffer.put(encodedResult);
		buffer.flip();

		// Transmit response frame
		commChannel.write(buffer);

		// Reset output stream
		byteArrayOutput.reset();
	}

	/**
	 * Read a number of bytes
	 */
	protected void readBytes(ByteBuffer bytes, int expectedBytes) throws IOException {
		// Read bytes until buffer is full
		while (bytes.position() < expectedBytes) {
			int res = commChannel.read(bytes);
			if (res == -1) {
				throw new ClosedChannelException();
			}
		}
	}

	/**
	 * Thread main function
	 */
	@Override
	public void run() {
		// Run forever (until socket is closed)
		while (true) {
			// Process inputs
			try {
				// Read response
				// - Wait for leading 4 byte header that contains frame length
				ByteBuffer rxBuffer1 = ByteBuffer.allocate(4);
				readBytes(rxBuffer1, 4);
				int frameSize = CoderTools.getInt32(rxBuffer1.array(), 0);
				logger.debug("Read Frame with size: " + frameSize);

				// Wait for frame to arrive
				ByteBuffer rxBuffer2 = ByteBuffer.allocate(frameSize);
				readBytes(rxBuffer2, frameSize);
				byte[] rxFrame = rxBuffer2.array();

				// Process input frame
				processInputFrame(rxFrame);
			} catch (IOException e) {
				// End when TCP socket is closed
				if (e instanceof ClosedChannelException) {
					break;
				}

				// Output error
				logger.error("Exception in run", e);
			}
		}
		try {
			commChannel.close();
		} catch (IOException e) {
			logger.debug("Exception while closing the comChannel ", e);
		}

		logger.debug(getName() + " Socket closed");
	}
}
