package com.juliacomputing.jldt.eclipse.ui.console;

import org.eclipse.dltk.console.*;

import java.io.*;
import java.util.List;

public class JuliaConsoleInterpreter implements IScriptInterpreter {

  private static final String ENCODING = "UTF8";

  private final Process process;
  private final BufferedWriter writer;
  private final BufferedReader reader;
  private String response;

  public JuliaConsoleInterpreter(final String path) {

    try {
      ProcessBuilder builder = new ProcessBuilder(path);
      builder.redirectErrorStream(true);
      process = builder.start();
      final OutputStream outputStream = process.getOutputStream();
      writer = new BufferedWriter(new OutputStreamWriter(outputStream, ENCODING));
      final InputStream inputStream = process.getInputStream();
      reader = new BufferedReader(new InputStreamReader(inputStream, "UTF8"));
    }
    catch (IOException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }

  }

  @Override
  public void addInitialListenerOperation(Runnable runnable) {

  }

  @Override
  public InputStream getInitialOutputStream() {
    return process.getInputStream();
  }

  @Override
  public boolean isValid() {
    return true;
  }

  @Override
  public void consoleConnected(IScriptConsoleIO iScriptConsoleIO) {
  }

  @Override
  public IScriptExecResult exec(String command) throws IOException {
    if (command != null && !command.isEmpty()) {
      writer.write(command);
      writer.newLine();
      writer.flush();
    }
    final StringBuilder responseBuilder = new StringBuilder();
    while (reader.ready()) {
      final String line = reader.readLine();
      responseBuilder.append(line);
      responseBuilder.append("\n");
    }
    response = responseBuilder.toString();
    return new ScriptExecResult(response);
  }

  @Override
  public int getState() {
    return response == null || response.trim().isEmpty() ? IScriptConsoleInterpreter.WAIT_CONTINUE_COMMAND
        : IScriptConsoleInterpreter.WAIT_NEW_COMMAND;
  }

  @Override
  public List<?> getCompletions(String s, int i) throws IOException {
    return null;
  }

  @Override
  public String getDescription(String s, int i) throws IOException {
    return null;
  }

  @Override
  public String[] getNames(String s) throws IOException {
    return new String[0];
  }

  @Override
  public void close() throws IOException {
    process.destroy();
  }
}

@@ -371,25 +371,117 @@
 e String
- response
+Builder block = new StringBuilder();%0A  private int state = IScriptConsoleInterpreter.WAIT_NEW_COMMAND
 ;%0A%0A  pub
@@ -529,17 +529,16 @@
 path) %7B%0A
-%0A
     try 
@@ -1493,59 +1493,101 @@
     
-if (command != null && !command.isEmpty()) 
+block.append(command);%0A    block.append(%22%5Cn%22);%0A    if(isIncomplete(block.toString()))
 %7B%0A      
 writ
@@ -1586,258 +1586,778 @@
     
-writer.write(command);%0A      writer.newLine();%0A      writer.flush(
+state = IScriptConsoleInterpreter.WAIT_USER_INPUT;%0A      return null;%0A    %7D%0A    final String response = execute(block.toString());%0A    block = new StringBuilder();%0A    state = IScriptConsoleInterpreter.WAIT_NEW_COMMAND;%0A    return new ScriptExecResult(response
 );%0A
-  
   %7D%0A
+%0A
   
-  final StringBuilder responseBuilder = new StringBuilder();%0A    while (reader.ready()) %7B%0A      final String line = reader.readLine();%0A      responseBuilder.append(l
+private boolean isIncomplete(final String block) throws IOException %7B%0A    final String parseCommand = String.format(%22parse(%5C%22%25s%5C%22,1; greedy=true, raise=false)%22, block);%0A    final String response = execute(parseCommand);%0A    return response.contains(%22incomplete%22);%0A  %7D%0A%0A  private String execute(String statement) throws IOException %7B%0A    writer.write(statement);%0A    writer.newLine();%0A    writer.flush();%0A    final StringBuilder response = new StringBuilder();%0A    response.append(reader.readL
 ine
+()
 );%0A
-  
     
@@ -2364,23 +2364,16 @@
 response
-Builder
 .append(
@@ -2387,101 +2387,147 @@
     
-%7D%0A    response = responseBuilder.toString();%0A    return new ScriptExecResult(response
+while (reader.ready()) %7B%0A      response.append(reader.readLine());%0A      response.append(%22%5Cn%22);%0A    %7D%0A    return response.toString(
 );%0A  %7D%0A%0A
   @O
@@ -2514,32 +2514,33 @@
 oString();%0A  %7D%0A%0A
+%0A
   @Override%0A  pu
@@ -2576,156 +2576,13 @@
 urn 
-response == null %7C%7C response.trim().isEmpty() ? IScriptConsoleInterpreter.WAIT_CONTINUE_COMMAND%0A        : IScriptConsoleInterpreter.WAIT_NEW_COMMAND
+state
 ;%0A  

update repl to check for incomplete statement/expression