/*
 * Implementation of a simple UDP Quote of the Day server *
 *
 *  Usage:
 *      java quoteUDPServer [-p port] -f file
 * Require argument:
 *      -f file: path to text file with quotes of day. A quote per line
 * Optional argument:
 *      -p port: UDP port where UDP Quote of the Day server is listening.
 *
 * @author Francisco M. Delicado
 * @version 10/10/2019
 */

import javax.xml.crypto.Data;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import java.net.*;

import static java.lang.System.exit;


public class quoteUDPServer {
    private static int port = 17; //Default quote of day port
    private static String file_name = null; //quote of day file text name.
    private static int nline; // Number of lines of file.
//-----------------------------------------------

    /**
     * Function to parse the command line
     *
     * @param line (String[]) command line parameters
     * @return a boolean value: true if command line is right, otherwise false
     */
    private static boolean ParseInput(String[] line) {
        String arg;
        BufferedReader file;
        try {
            for (int i = 0; i < line.length; i++) {
                arg = line[i];
                if (arg.equals("-p"))
                    port = Integer.parseInt(line[++i]);
                else if (arg.equals("-f")) {
                    file_name = line[++i];
                    file = new BufferedReader(new FileReader(file_name)); //quote of day text file.
                    nline = (int) file.lines().count();
                    file.close();
                } else {
                    System.out.println("Usage error: Incorrect parameter(s)");
                    PrintUsage();
                    return false;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("Quote of day text file doesn't exist: " + file_name);
            PrintUsage();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
        }

        //Port is out of limits.
        return ((port > 0) && (port <= 65535));
    }

//---------------------------------------------

    /**
     * Print program usage
     */
    private static void PrintUsage() {
        final String usage = "java quoteUDPServer [-p port] -f file"
                + "\n\nDESCRIPTION: Quote of day UDP Server"
                + "\n\nArguments:"
                + "\n\t-p port (optional): port is the  UDP of quote of day server. Default value 17."
                + "\n\t-f file (require): path to text file with quotes of day. A quote per line.\n";
        System.out.println(usage);
    }
//---------------------------------------------

    /**
     * Obtain a new quote of day
     *
     * @return a String with a new quote of day.
     */
    private static String NewQuote() {
        String line = null;
        long index = (long) (Math.random() * nline);
        try {
            BufferedReader file = new BufferedReader(new FileReader(file_name));
            for (int i = 0; i < index; i++) {
                file.readLine();
            }
            line = file.readLine();
        } catch (FileNotFoundException fe) {
            System.out.println("File not found: " + file_name);
            fe.printStackTrace();
        } catch (IOException e) {
            System.out.println("IOException reading file.");
            e.printStackTrace();
        }
        return line;
    }

    public static void main(String[] args) {

        if (!ParseInput(args)) {
            exit(1);
        }

        try (DatagramSocket socket =new DatagramSocket(port)){
            byte[] buffer = new byte[1024];

            while (true) {
                // TODO 1: Esperar por una petición de "cita del día"
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet);

                // TODO 2: Obtener dirección IP y puerto del cliente que realizó la petición.
                // Obtengo en el String quote la "cita del día".
                String quote = NewQuote();

                // TODO 3: Enviar la "cita del día" guardada en la variable "String quote" al cliente que realizó la petición.
                byte [] sendData = quote.getBytes();
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());

                socket.send(sendPacket);
            }

        } catch(IOException e){
            e.printStackTrace();
        }
    }
}
