package fr.upem.net.udp;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class MassiveClientBetterUpperCaseUDP {

	public static final int BUFFER_SIZE = 1024;

	public static void usage() {
		System.out.println("Usage : MassiveClientUpperCaseUDP host port charset file");
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		// check and retrieve parameters
		if (args.length != 4) {
			usage();
			return;
		}
		String host = args[0];
		int port = Integer.valueOf(args[1]);
		String charsetName = args[2];
		
		List<String> inList = new LinkedList<>();
		Path pathIn = FileSystems.getDefault().getPath(args[3]);
		try (Scanner scan = new Scanner(pathIn)) {
			while(scan.hasNextLine()) {
				inList.add(scan.nextLine());
			}
		}

		// prepare DatagramChannel and destination
		SocketAddress dest = new InetSocketAddress(host, port);
		try (DatagramChannel dc = DatagramChannel.open()) {

			final BlockingQueue<String> queue = // TODO

			Thread listener = new Thread(()->{
				ByteBuffer recvBuf = // TODO
				try {
					while(!Thread.currentThread().isInterrupted()) {
						// TODO (receive buffer and put corresponding message in queue)
					}
				} catch (InterruptedException ie) {
					System.err.println("Listener interrupted while waiting to put message in the queue");
				} catch(ClosedByInterruptException cbie) {
					System.err.println("Listener interrupted while receiving");
				} catch(IOException ioe) {
					System.err.println("Listener stopped by an IO error");
					ioe.printStackTrace();
				} 
			}
					);
			listener.start();

			List<String> outList = new ArrayList<>(inList.size());

			for(String line : inList) {
				// TODO (send the message to server (possibly several time), 
				// poll the answer from the queue and 
				// store it into outList)
			}

			Path pathOut = FileSystems.getDefault().getPath(args[3]+"_UperCase");
			try (ByteChannel out = Files.newByteChannel(pathOut, StandardOpenOption.WRITE, 
					StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
				Charset defaultCharset = Charset.defaultCharset();
				ByteBuffer newLine = defaultCharset.encode("\n");
				for(String line : outList) {
					out.write(defaultCharset.encode(line));
					out.write(newLine); 
					newLine.flip();
				}
			}
		}
	}
}
