package reseau;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Logger;

/**
 * @author Dream Team
 */
final class JavaNetworkCommunication {

    private static final Logger logger = Logger.getLogger(JavaNetworkCommunication.class.getCanonicalName());

    private static final boolean DEBUG = false;
    private static final boolean SUCCESS = false;
    private static int testGenerator = 0;
    private static final String TEMPLATE_FOLDER = "resources/message-template/";

    private static final String HOST = "localhost";
    private static final int PORT = 5026;

    private static Socket serverSocket = null;

    public static synchronized Message sendMessage(Message mess) throws UnauthorizedOperationException, DataNotFoundException {
        if (DEBUG)
            return testSendMessage(mess);
        else
            return realSendMessage(mess);
    }

    private static synchronized Message realSendMessage(Message mess) throws UnauthorizedOperationException, DataNotFoundException {
        try {
            logger.finer("Request  : " + mess.toString());

            serverSocket = new Socket(HOST, PORT);

            Writer requestWriter = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));


            requestWriter.write(mess.toString());
            requestWriter.write("\n\n");
            requestWriter.flush();

            StringBuilder responseData = new StringBuilder();
            String line = null;

            while ((line = responseReader.readLine()) != null){
                responseData.append(line + "\n");
            }

            logger.finer("Response : " + responseData.toString());

            serverSocket.close();
            serverSocket = null;

            return MessageAbstractFactory.createResponseMessage(responseData.toString());
        } catch (UnknownHostException e) {
            throw new NetworkException("Error during network communication", e);
        } catch (IOException e) {
            throw new NetworkException("Error during network communication", e);
        }
    }

    private static synchronized Message testSendMessage(Message mess) throws UnauthorizedOperationException, DataNotFoundException {
        logger.info("DEBUG mode ON");
        logger.finer("Request  : " + mess.toString());

        String testResponse = selectTestResponse(mess);

        logger.finer("Test response : " + testResponse);

        try {
            Writer requestWriter = new BufferedWriter(new FileWriter(String.format("test-request-%d.request", ++testGenerator)));
            BufferedReader responseReader = new BufferedReader(new FileReader(testResponse));

            requestWriter.write(mess.toString());
            requestWriter.flush();

            StringBuilder responseData = new StringBuilder();
            String line = null;

            while ((line = responseReader.readLine()) != null)
                responseData.append(line + "\n");

            logger.finer("Response : " + responseData.toString());

            return MessageAbstractFactory.createResponseMessage(responseData.toString());
        } catch (UnknownHostException e) {
            throw new NetworkException("Error during network communication", e);
        } catch (IOException e) {
            throw new NetworkException("Error during network communication", e);
        }
    }

    private static String selectTestResponse(Message mess) {

        if (mess.getMessageAction().equals("GET")) {
            if (mess.getMessageURL().contains("authentify"))       //login
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "login-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/problems?"))      //problems
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read-problems-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/problems/"))      //problem
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-problem-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().endsWith("/users"))         //users
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read-users-sucess.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/users/"))         //user
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-user-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().endsWith("/results?"))       //results
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read-results-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/results/"))      //result
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read-result-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().endsWith("/benchmarks?"))    //benchkmarks
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "resolve-benchmarks-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/benchmarks/"))     //benchmark
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "resolve-benchmark-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().endsWith("/groups"))       //groups
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read-groups-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/groups/"))    //group
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-group-success.response"
                                : "fail-not-found.response");

        } else if (mess.getMessageAction().equals("POST")) {
            if (mess.getMessageURL().contains("/groups"))             //group
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "create-group-success.response"
                                : "fail-forbidden.response");
            else if (mess.getMessageURL().contains("/problems"))      //problem
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "create-problem-success.response"
                                : "fail-forbidden.response");
            else if (mess.getMessageURL().contains("/files"))         //file
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "create-problem-file-transfer-success.response"
                                : "file-transfer-fail.response");
            else if (mess.getMessageURL().contains("/users"))         //user
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "create-user-success.response"
                                : "fail-forbidden.response");
            else if (mess.getMessageURL().contains("/results"))       //result
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "resolve-simple-success.response"
                                : "fail-precondition.response");
            else if (mess.getMessageURL().contains("/benchmarks"))    //benchmark
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "resolve-benchmark-success.response"
                                : "fail-precondition.response");
        } else if (mess.getMessageAction().equals("PUT")) {
            if (mess.getMessageURL().contains("/groups/"))             //group
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-group-success.response"
                                : "fail-forbidden.response");
            else if (mess.getMessageURL().contains("/problems/"))      //problem
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-problem-success.response"
                                : "fail-forbidden.response");
            else if (mess.getMessageURL().contains("/users/"))         //user
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "read.update-user-success.response"
                                : "fail-forbidden.response");
        } else if (mess.getMessageAction().equals("DELETE")) {
            if (mess.getMessageURL().contains("/groups"))             //group
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "delete-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/problems"))      //problem
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "delete-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/users"))         //user
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "delete-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/results"))       //result
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "delete-success.response"
                                : "fail-not-found.response");
            else if (mess.getMessageURL().contains("/benchmarks"))    //benchmark
                return TEMPLATE_FOLDER + (
                        SUCCESS
                                ? "delete-success.response"
                                : "fail-not-found.response");
        }

        return null;
    }

}
