package com.reason.ide.format;


import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.reason.Platform;
import com.reason.Streams;
import com.reason.ide.RmlNotification;

import java.io.*;

class RefmtProcess {

    private final String m_refmtBin;
    private final Logger m_log;

    RefmtProcess() {
        m_refmtBin = Platform.getBinary("REASON_REFMT_BIN", "reasonRefmt", "node_modules/bs-platform/lib/refmt3.exe");
        m_log = Logger.getInstance("ReasonML.refmt");
    }

    String run(Project project, String format, String code) {
        String refmtPath = Platform.getBinaryPath(project, m_refmtBin);
        if (refmtPath == null) {
            refmtPath = Platform.getBinaryPath(project, "node_modules/bs-platform/bin/refmt3.exe");
            if (refmtPath == null) {
                // Use a watcher ?
                return code;
            }
        }

        ProcessBuilder processBuilder = new ProcessBuilder(refmtPath, "--parse", format, "--print", format);

        Process refmt = null;
        try {
            refmt = processBuilder.start();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(refmt.getOutputStream()));
            BufferedReader reader = new BufferedReader(new InputStreamReader(refmt.getInputStream()));
            BufferedReader errReader = new BufferedReader(new InputStreamReader(refmt.getErrorStream()));

            writer.write(code);
            writer.close();
            Streams.waitUntilReady(reader, errReader);

            StringBuilder msgBuffer = new StringBuilder();
            if (errReader.ready()) {
                errReader.lines().forEach(line -> msgBuffer.append(line).append(System.lineSeparator()));
                Notifications.Bus.notify(new RmlNotification("Reformat", msgBuffer.toString(), NotificationType.ERROR));
            } else {
                reader.lines().forEach(line -> msgBuffer.append(line).append('\n'));
                String newText = msgBuffer.toString();
                if (!code.isEmpty() && !newText.isEmpty()) { // additional protection
                    return newText;
                }
            }
        } catch (IOException | RuntimeException e) {
            m_log.error(e.getMessage());
        } finally {
            if (refmt != null && refmt.isAlive()) {
                refmt.destroy();
            }
        }

        // Something bad happened, do nothing
        return code;
    }
}

@@ -353,16 +353,80 @@
 cess %7B%0A%0A
+    private final String BS_PATH = %22node_modules/bs-platform%22;%0A%0A
     priv
@@ -587,33 +587,19 @@
 t%22, 
-%22node_modules/bs-platform
+BS_PATH + %22
 /lib
@@ -600,25 +600,24 @@
  %22/lib/refmt
-3
 .exe%22);%0A    
@@ -832,32 +832,65 @@
 Path == null) %7B%0A
+            // Test old versions%0A
             refm
@@ -933,33 +933,146 @@
 ct, 
-%22node_modules/bs-platform
+BS_PATH + %22/lib/refmt3.exe%22);%0A            if (refmtPath == null) %7B%0A                refmtPath = Platform.getBinaryPath(project, BS_PATH + %22
 /bin
@@ -1090,32 +1090,36 @@
 %22);%0A            
+   
+ 
 if (refmtPath ==
@@ -1143,16 +1143,20 @@
         
+    
 // Use a
@@ -1166,16 +1166,20 @@
 tcher ?%0A
+    
         
@@ -1195,24 +1195,42 @@
 eturn code;%0A
+                %7D%0A
             

fix #40