package cz.net21.ttulka.thistledb.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import org.json.JSONObject;

/**
 * Created by ttulka
 * <p>
 * Processing a query.
 */
class QueryExecutor {

    public static final String ACCEPTED = "ACCEPTED";
    public static final String ERROR = "ERROR";
    public static final String INVALID = "INVALID";
    public static final String OKAY = "OKAY";

    private final Socket socket;
    private final String query;

    BufferedReader in;

    public QueryExecutor(Socket socket, String nativeQuery) {
        this.socket = socket;
        this.query = nativeQuery;
    }

    public void executeQuery() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println(query);

        } catch (Exception e) {
            throw new ClientException("Cannot send a query to socket: " + query, e);
        }
    }

    public JSONObject getNextResult() {
        try {
            String result = in.readLine();

            if (result != null && !result.isEmpty()) {

                if (result.startsWith(ACCEPTED)) {
                    return getNextResult();
                }
                if (result.startsWith(ERROR)) {
                    return error(result);
                }
                if (result.startsWith(INVALID)) {
                    return invalid(result);
                }
                if (result.startsWith(OKAY)) {
                    return okay();
                }
                return new JSONObject(result);
            }
            return null;

        } catch (Exception e) {
            throw new ClientException("Error by receiving results from server.", e);
        }
    }

    private JSONObject error(String result) {
        String msg = result.substring(ERROR.length());
        return new JSONObject("{\"status\":\"error\", \"message\":\"" + msg + "\"}");
    }

    private JSONObject invalid(String result) {
        String msg = result.substring(INVALID.length());
        return new JSONObject("{\"status\":\"invalid\", \"message\":\"" + msg + "\"}");
    }

    private JSONObject okay() {
        return new JSONObject("{\"status\":\"okay\"}");
    }
}

@@ -536,16 +536,24 @@
 y;%0A%0A    
+private 
 Buffered
@@ -705,136 +705,155 @@
     
-public void executeQuery() %7B
+/**%0A     * Executes a query.
 %0A     
+*%0A
    
-try %7B%0A   
+  * @throws ClientException when execution goes wrong%0A
      
+*/%0A
     
-in = new BufferedReader(new InputStreamReader(socket.getInputStream()));%0A
+public void executeQuery() %7B%0A        try %7B
 %0A   
@@ -957,24 +957,110 @@
 ln(query);%0A%0A
+            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));%0A%0A
         %7D ca
@@ -1189,43 +1189,381 @@
     
-public JSONObject getNextResult() %7B
+/**%0A     * Retrieves a result of the query.%0A     *%0A     * @return the result%0A     * @throws ClientException       when retrieving goes wrong%0A     * @throws IllegalStateException when the query was not executed yet%0A     */%0A    public JSONObject getNextResult() %7B%0A        if (in == null) %7B%0A            throw new IllegalStateException(%22Query was not executed yet.%22);%0A        %7D
 %0A   

input after out