package qubit.cucumber.editor.format;

import gherkin.I18nLexer;
import gherkin.Lexer;
import gherkin.formatter.PrettyFormatter;
import gherkin.parser.Parser;
import java.io.StringWriter;
import javax.swing.text.BadLocationException;
import org.netbeans.modules.editor.indent.spi.Context;
import org.netbeans.modules.editor.indent.spi.ExtraLock;
import org.netbeans.modules.editor.indent.spi.ReformatTask;
import org.openide.windows.IOProvider;
import org.openide.windows.InputOutput;
import org.openide.windows.OutputWriter;

class GherkinFormatTask implements ReformatTask {

    private final Context context;

    public GherkinFormatTask(Context context) {
        this.context = context;
    }

    public void reformat() throws BadLocationException {
        try {
            String source = context.document().getText(0, context.document().getLength());
            StringWriter reformattedWriter = new StringWriter();
            Parser parser = new Parser(new PrettyFormatter(reformattedWriter, true));
            Lexer lexer = new I18nLexer(parser);
            lexer.scan(source);
            writeSource(reformattedWriter.getBuffer().toString());
        } catch (Exception e) {
            showError(e);
        }
    }

    private void writeSource(String reformattedSource) throws BadLocationException {
        context.document().remove(0, context.document().getLength());
        context.document().insertString(0, reformattedSource, null);
    }

    public ExtraLock reformatLock() {
        return null;
    }

    private void showError(Exception e) {
        InputOutput io;
        OutputWriter outputWriter;
        io = IOProvider.getDefault().getIO("Cucumber", false);
        io.select();
        outputWriter = io.getOut();
        e.printStackTrace(outputWriter);
        // This seems to block the IDE
        // JOptionPane.showMessageDialog(null, e, e.getMessage(), JOptionPane.ERROR_MESSAGE);
    }
}

@@ -686,32 +686,478 @@
 context;%0A    %7D%0A%0A
+    private boolean doReformat() %7B%0A        boolean format = true;%0A        StackTraceElement%5B%5D calling_stack = new Exception().getStackTrace();%0A        for (StackTraceElement stackTraceElement : calling_stack) %7B%0A            if (stackTraceElement.getClassName().equals(%22org.netbeans.lib.editor.codetemplates.CodeTemplateInsertHandler%22)) %7B%0A                format = false;%0A                break;%0A            %7D%0A        %7D%0A        return format;%0A    %7D%0A%0A
     public void 
@@ -1189,32 +1189,64 @@
 tionException %7B%0A
+        if (doReformat()) %7B%0A    
         try %7B%0A  
@@ -1243,16 +1243,20 @@
   try %7B%0A
+    
         
@@ -1346,24 +1346,28 @@
             
+  
+  
 StringWriter
@@ -1403,24 +1403,28 @@
 ngWriter();%0A
+    
             
@@ -1509,16 +1509,20 @@
         
+  
+  
 Lexer le
@@ -1562,16 +1562,20 @@
         
+    
 lexer.sc
@@ -1598,16 +1598,20 @@
         
+  
+  
 writeSou
@@ -1665,16 +1665,20 @@
         
+    
 %7D catch 
@@ -1705,16 +1705,20 @@
         
+  
+  
 showErro
@@ -1719,24 +1719,38 @@
 owError(e);%0A
+            %7D%0A
         %7D%0A  

Fix Formatter (don't format if code template used)