package cz.net21.ttulka.thistledb.console;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;

import cz.net21.ttulka.thistledb.client.Client;
import cz.net21.ttulka.thistledb.client.ClientException;
import lombok.extern.apachecommons.CommonsLog;

/**
 * Created by ttulka
 * <p>
 * The admin console.
 */
@CommonsLog
public class Console {

    private final Client client;

    private final InputStream in;
    private final PrintStream out;
    private final PrintStream err;

    public Console() {
        this(Client.DEFAULT_HOST, Client.DEFAULT_PORT);
    }

    public Console(String host) {
        this(host, Client.DEFAULT_PORT);
    }

    public Console(int port) {
        this(Client.DEFAULT_HOST, port);
    }

    public Console(String host, int port) {
        this(host, port, System.in, System.out, System.err);
    }

    public Console(String host, int port, InputStream in, PrintStream out, PrintStream err) {
        this.in = in;
        this.out = out;
        this.err = err;

        this.client = new Client(host, port);
    }

    public void start() {
        printLogo();

        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        String command = null;
        out.println("\nType 'quit' to stop the server and exit the console.");
        do {
            try {
                out.print("$ ");
                command = br.readLine();
                if (command != null && !command.trim().isEmpty()) {
                    command = command.trim();

                    if ("quit".equals(command)) {
                        break;
                    }

                    executeQuery(command);
                }
            } catch (IOException e) {
                err.println("Invalid user input!");
            } catch (ClientException e) {
                err.println("Client error: " + e.getMessage());
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } while (command != null);

        out.println("\nBye!");
    }

    void executeQuery(String query) {
        List<String> result = client.executeQueryBlocking(query);

        out.println("\nResult(s):");

        if (result.isEmpty()) {
            result.add("{}");
        }

        Iterator<String> iterator = result.iterator();
        while (iterator.hasNext()) {
            formatJsonResult(iterator.next(), !iterator.hasNext());
        }
    }

    private void formatJsonResult(String json, boolean last) {
        new JsonFormatter(json, out).formatJsonResult(last);
    }

    private void printLogo() {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(Console.class.getResourceAsStream("/logo.txt")))) {
            String line;
            while ((line = reader.readLine()) != null) {
                out.println(line);
            }
        } catch (Throwable t) {
            // ignore
        }
    }
}

@@ -1678,16 +1678,42 @@
     if (
+%22exit%22.equals(command) %7C%7C 
 %22quit%22.e

exit to the console