package fr.umlv.guess;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.Random;


public class ClueUDPServer {
	private final static int MAX_BUFFER_SIZE = 1024;
	private final static int INT_SIZE = 4;
	private final static Charset INPUT_CHARSET = Charset.forName("iso-8859-15");
	private final DatagramSocket ds;

	public ClueUDPServer(int listeningPort) throws SocketException {
		ds = new DatagramSocket(listeningPort);
	}

	public void launch() throws IOException {
		byte[] receiveBuffer = new byte[MAX_BUFFER_SIZE];
		byte[] sendBuffer = new byte[INT_SIZE];
		DatagramPacket dp = new DatagramPacket(receiveBuffer, 0, MAX_BUFFER_SIZE);
		String secret = generateSimpleSecret();
		while (!Thread.currentThread().isInterrupted()) {
			System.err.println("secret is: " + secret);
			ds.receive(dp);
			String msg = new String(receiveBuffer, 0, dp.getLength(), INPUT_CHARSET);
			int distance = msg.compareTo(secret);
			intToByteArray(distance, sendBuffer);
			System.out.println(dp.getSocketAddress() + " send me: " + msg + 
					" which is at a distance " + distance + " from secret");
			dp.setData(sendBuffer);
			ds.send(dp);
			if(distance == 0) 
				secret = generateSimpleSecret();
			dp.setData(receiveBuffer);
		}
		ds.close();
	}
	
	/**
	 * Returns a randomly generated String of size between 6 and 10 characters
	 * and that only contains characters among the following:
	 * !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
	 *		
	 * @return the random String
	 */
	private static String generateSimpleSecret() {
		Random rand = new Random(System.currentTimeMillis());
		// size of secret will be between 6 and 10 characters 
		char[] secret = new char[6 + rand.nextInt(5)];
		for(int i=0; i<secret.length; i++) {
			secret[i] = (char) ('!' +  rand.nextInt(94));
			if (secret[i] == ' ')
				System.out.println("J'ai tiré l'espace" + ((int)secret[i]));
		}
		return new String(secret,0,secret.length);
	}

	public static void intToByteArray(int value, byte[] array) {
		if (array.length != INT_SIZE)
			throw new IllegalArgumentException("Incompatible size of byte array for an int: " + array.length);
		for(int b = INT_SIZE-1; b>=0; b--) {
			array[b] = (byte) (value & 0xFF);
			value = value >> 8;
		}
	}
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		if (args.length < 1) {
			System.err.println("Usage: java fr.umlv.guess.ClueUDPServer <listeningPort>");
			System.exit(0);
		}
		ClueUDPServer server = new ClueUDPServer(Integer.parseInt(args[0]));
		server.launch();

	}
}
