package xilodyne.redis;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
//import java.nio.charset.StandardCharsets;
import java.util.Base64;

import org.apache.commons.io.IOUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.BinaryJedis;

/**
 * @author Austin Davis Holiday (aholiday@xilodyne.com)
 *
 */
public class TestPythonDataExchangeViaRedis {

	static Jedis jedis;
	static BinaryJedis binJedis;
	static String Redis_IPAdd = "192.168.159.39";
	static String inputImage1 = "./images/input/Colorado-1.jpg";
	static String inputImage2 = "./images/input/Colorado-2.jpg";
	static String inputImage3 = "./images/input/Colorado-3.jpg";
	static String outputImage = "./images/output/newimage.jpg";

	public static void main(String[] args) throws IOException {

		System.out.println("*********************");
		System.out.println("Test Java data exchange with redis.");

		jedis = new Jedis(Redis_IPAdd);
		System.out.println("Redis connection: " + Redis_IPAdd);

		System.out.println();
		System.out.println("Send and Receive TEXT from redis...");
		jedis.set("food", "is good");
		System.out.println("Set \"is good\" for key: \"food\"");
		String value = jedis.get("food");

		System.out.println("Get key \"food\": " + value);

		binJedis = new BinaryJedis(Redis_IPAdd);
		// System.out.println("Redis binary connection: " + Redis_IPAdd +": " +
		// binJedis.info());
		System.out.println();
		System.out.println();
		System.out.println("Redis binary connection: " + Redis_IPAdd);
		System.out.println();
		System.out.println("Send and Receive BINARY data (image) with BINARY key...");
		InputStream in = new FileInputStream(inputImage2);
		byte[] binKey = new byte[101];

		byte[] imageBytes = IOUtils.toByteArray(in);
		binJedis.set(binKey, imageBytes);
//		System.out.println("Set image \"" + inputImage2 + "\" for binkey: " + Base64.getDecoder().decode(binKey));
		System.out.println("Set image \"" + inputImage2 + "\" for binkey: " + binKey);

		byte[] oldImg = binJedis.get(binKey);
		System.out.println("Get image of binKey");

		OutputStream out = new FileOutputStream(outputImage);
		IOUtils.write(oldImg, out);

		in.close();
		out.close();

		testPythonExchange(inputImage1);
		testPythonExchange(inputImage2);
		testPythonExchange(inputImage3);
	}

	/*
	 * Increment redis counter, python sees increment, creates infer+count with
	 * value when java sees infer+count, gets value, deletes infer+count
	 * 
	 * key deletion is preferred over key update for performance reasons and in case
	 * of program crash
	 */
	public static void testPythonExchange(String image) throws IOException {
		System.out.println();
		System.out.println("*********************");
		System.out.println("Test Java data exchange with Python via redis.");
		System.out.println("Send as BINARY data: " + image);
		System.out.println();

		InputStream in = new FileInputStream(image);
		byte[] byteArrayImage = IOUtils.toByteArray(in);
		in.close();

		jedis.incr("counter");
		String count = jedis.get("counter");
		jedis.set("img:" + count, count);
		String val = jedis.get("img:" + count);
		System.out.println("Get next redis \"counter\" increment: " + count);
		System.out.println("Set new java key: \"img:" + count + "\"");
		System.out.println("Get (verify) redis java key: " + val);

		binJedis.set(("img:" + count).getBytes(), byteArrayImage);
		System.out.println("Set binary image for key: " + val);

		String pythonResponse = "";
		boolean not_found = true;
		int loopcount = 0;
		System.out.println("Waiting for response for python key: \"infer:" + count + "\"");
		while (not_found) {
			pythonResponse = jedis.get("infer:" + count);
			if (pythonResponse != null) {
				not_found = false;
			}
			loopcount++;
			if ((loopcount % 1000) == 0) {
				System.out.print("*");
				if (loopcount == 100000) {
					System.out.println();
					loopcount = 0;
				}
			}
		}
		System.out.println();
		if (pythonResponse.equalsIgnoreCase("0")) {
			System.out.println("Python response value is:  0");
		} else {
			System.out.println("Python response value is:  1");
		}
		jedis.unlink("infer:" + count);
		System.out.println("Deleted redis python key \"infer:" + count + "\"");
	}
}
