package bagaturchess.bitboard.bughouse;

import java.io.*;

public class StockfishThread {

    /*

    Thread that handles all stockfish communication.
    When building, change EXEC to your destination of stockfish.

    Methods mainly just manage the I/O of stockfish

     */

    private static final String EXEC =
            "";

    private Process engineProcess;
    private BufferedReader processReader;
    private OutputStreamWriter processWriter;

    /*
    Starts Stockfish engine, assigns OutPutStream writer and InputStreamReader
     */

    public boolean startEngine() {
        try {
            engineProcess = Runtime.getRuntime().exec(EXEC);
            processReader = new BufferedReader(new InputStreamReader(engineProcess.getInputStream()));
            processWriter = new OutputStreamWriter(engineProcess.getOutputStream());
        } catch (Exception e) {
            return false;
        }
        return true;
    }


    public void sendCommand(String command) {
        try {
            processWriter.write(command + "\n");
            processWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public String getOutput(int waitTime) {
        StringBuilder buffer = new StringBuilder();
        try {
            Thread.sleep(waitTime);
            sendCommand("isready");
            while (true) {
                String text = processReader.readLine();
                if (text.equals("readyok"))
                    break;
                else
                    buffer.append(text).append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }


    public void drawBoard(String fen) {
        sendCommand("position fen " + fen);
        sendCommand("d");

        String[] rows = getOutput(0).split("\n");

        for (int i = 1; i < 18; i++) {
            System.out.println(rows[i]);
        }
    }

    public float getEvalScore(String fen, int waitTime) {
        sendCommand("position fen " + fen);
        sendCommand("go movetime " + waitTime);

        float evalScore = 0.0f;
        String[] dump = getOutput(waitTime + 20).split("\n");

        for (int i = dump.length - 1; i >= 0; i--) {
            if (dump[i].startsWith("info depth ")) {
                try {
                    evalScore = Float.parseFloat(dump[i].split("score cp ")[1]
                            .split(" nodes")[0]);
                } catch(Exception e) {
                    if (dump[i].contains("score mate ")) return 9999;
                }
            }
        }
        return evalScore/100;
    }

    public float getStaticEvalScore(String fen, int waitTime) {
        sendCommand("position fen " + fen);
        sendCommand("eval");

        float evalScore = 0.0f;
        String[] dump = getOutput(waitTime + 10).split("\n");
        try {
            evalScore = Float.parseFloat(dump[dump.length-1].split("Final evaluation:")[1]
                    .split("\\s+")[0]);
        } catch(Exception ignored) {
        }
        return evalScore;
    }

}
