package ejf;

import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.TextEdit;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.Properties;

public class Main {

    public static void main(final String[] args) {
        if (args.length < 2) {
            System.err.println("usage: eclipse-formatter <style.xml> <file1.java> <file2.java> ...");
            System.exit(1);
        }
        boolean someFailed = false;
        final Formatter fm = new Formatter(args[0]);
        for (final String f : Arrays.copyOfRange(args, 1, args.length))
            try {
                write(f, fm.format(read(f)));
            } catch (Exception e) {
                System.err.println(e.toString() + ": " + f);
                someFailed = true;
            }
        if (someFailed) System.exit(2);
    }

    private static String read(final String path) throws IOException {
        return new String(Files.readAllBytes(Paths.get(path)));
    }

    private static void write(final String path, final String content) throws IOException {
        Files.write(Paths.get(path), content.getBytes());
    }

    private static class Formatter {
        private final CodeFormatter formatter;

        public Formatter(final String xmlFile) {
            formatter = new DefaultCodeFormatter(props(xmlFile));
        }

        public String format(final String input) throws BadLocationException {
            final IDocument doc = new Document();
            doc.set(input);
            final TextEdit edit = formatter.format(
                    CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS,
                    input, 0, input.length(), 0, "\n");
            if (edit == null) throw new RuntimeException("formatting failed");
            edit.apply(doc);
            return doc.get();
        }

        private static Properties props(final String xmlFile) {
            return new Properties();
        }
    }


}

@@ -378,16 +378,49 @@
 odeList;
+%0Aimport org.xml.sax.SAXException;
 %0A%0Aimport
@@ -462,16 +462,71 @@
 actory;%0A
+import javax.xml.parsers.ParserConfigurationException;%0A
 import j
@@ -914,17 +914,17 @@
 em.exit(
-1
+3
 );%0A     
@@ -964,16 +964,34 @@
  false;%0A
+        try %7B%0A    
         
@@ -1043,16 +1043,20 @@
         
+   
+ 
 for (fin
@@ -1115,38 +1115,46 @@
 h))%0A            
+    
 try %7B%0A
+    
                 
@@ -1195,16 +1195,20 @@
         
+  
+  
 %7D catch 
@@ -1219,24 +1219,28 @@
 eption e) %7B%0A
+    
             
@@ -1288,16 +1288,20 @@
 %22 + f);%0A
+    
         
@@ -1331,34 +1331,42 @@
 ue;%0A            
-%7D%0A
+    %7D%0A    
         if (some
@@ -1389,11 +1389,127 @@
 xit(
-2);
+1);%0A        %7D catch (Exception e) %7B%0A            System.err.println(e.toString());%0A            System.exit(2);%0A        %7D
 %0A   
@@ -1934,32 +1934,95 @@
  String xmlFile)
+ throws IOException, SAXException, ParserConfigurationException
  %7B%0A            f
@@ -2654,45 +2654,1184 @@
 le) 
-%7B%0A            return new Properties()
+throws ParserConfigurationException, IOException, SAXException %7B%0A            Properties r = new Properties();%0A%0A            org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);%0A            doc.getDocumentElement().normalize();%0A%0A            NodeList profiles = doc.getElementsByTagName(%22profile%22);%0A            if (profiles.getLength() != 1)%0A                throw new RuntimeException(%22XML style should contain exactly one %3Cprofile/%3E: %22 + xmlFile);%0A%0A            Node profile = profiles.item(0);%0A            if (profile.getNodeType() == Node.ELEMENT_NODE) %7B%0A                NodeList settings = ((Element) profile).getElementsByTagName(%22setting%22);%0A                for (int i = 0; i %3C settings.getLength(); i++) %7B%0A                    Node setting = settings.item(i);%0A                    if (setting.getNodeType() == Node.ELEMENT_NODE) %7B%0A                        String id = ((Element) setting).getAttribute(%22id%22);%0A                        String value = ((Element) setting).getAttribute(%22value%22);%0A                        r.setProperty(id.trim(), value.trim());%0A                    %7D%0A                %7D%0A            %7D%0A%0A            return r
 ;%0A  
@@ -3842,14 +3842,13 @@
   %7D%0A
+
     %7D%0A%0A
-%0A
 %7D%0A

Read the XML style