package com.github.jonathonrichardson.java2ts;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;

/**
 * Created by jon on 3/24/17.
 */
public class Compiler {
    private Manifest manifest;
    private Namespace namespace = new Namespace();

    public Compiler(Manifest manifest) {
        this.manifest = manifest;
    }

    public CompilerOutput compile(OutputStream outputStream) throws ClassNotFoundException, IOException {
        CompilerOutput output = new CompilerOutput();
        output.outfiles = new HashMap<>();

        for (String className : this.manifest.fullyQualifiedClassNames) {
            Class clazz = this.getClass().getClassLoader().loadClass(className);
            this.namespace.addClass(clazz);
        }

        this.namespace.write(outputStream);

        return output;
    }

    public static void main() throws IOException, ClassNotFoundException {
        Manifest mainManifest = new Manifest();
        ObjectMapper mapper = new ObjectMapper();

        Enumeration<URL> manifests = Compiler.class.getClassLoader().getResources("/java2ts/manifest.json");
        while(manifests.hasMoreElements()) {
            Manifest curManifest = mapper.readValue(manifests.nextElement().openStream(), Manifest.class);
            mainManifest.fullyQualifiedClassNames.addAll(curManifest.fullyQualifiedClassNames);
        }

        Compiler compiler = new Compiler(mainManifest);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        compiler.compile(buffer);

        Path outFilePath = Paths.get(System.getProperty("user.dir"), "GeneratedFromJava.ts");
        Files.write(outFilePath, buffer.toByteArray());
    }
}

@@ -348,16 +348,64 @@
 HashMap;
+%0Aimport java.util.HashSet;%0Aimport java.util.Set;
 %0A%0A/**%0A *
@@ -841,70 +841,178 @@
     
-for (
+Set%3C
 String
+%3E
  class
-Name : this.manifest.fullyQualifiedClassNames
+esToCompile = new HashSet%3C%3E();%0A        classesToCompile.addAll(this.manifest.fullyQualifiedClassNames);%0A%0A        for (String className : classesToCompile
 ) %7B%0A
@@ -1254,52 +1254,22 @@
 ain(
-) throws IOException, ClassNotFoundException
+String%5B%5D args)
  %7B%0A 
@@ -1378,54 +1378,145 @@
     
-Enumeration%3CURL%3E manifests = Compiler.class.ge
+try %7B%0A            //System.out.println(%22Gathering manifests%22);%0A%0A            Enumeration%3CURL%3E manifests = Thread.currentThread().getContex
 tCla
@@ -1540,17 +1540,16 @@
 ources(%22
-/
 java2ts/
@@ -1577,13 +1577,18 @@
     
+ 
+   
 while
+ 
 (man
@@ -1631,103 +1631,519 @@
     
-Manifest curManifest = mapper.readValue(manifests.nextElement().openStream(), Manifest.class);%0A
+    URL manifestURL = manifests.nextElement();%0A                System.out.println(String.format(%0A                        %22Reading manifest: %25s%22,%0A                        manifestURL.toString()%0A                ));%0A%0A                Manifest curManifest = mapper.readValue(manifestURL.openStream(), Manifest.class);%0A                //System.out.println(String.format(%0A                //        %22Manifest has %25s lines%22,%0A                //        curManifest.fullyQualifiedClassNames.size()%0A                //));%0A    
     
@@ -2234,32 +2234,36 @@
 Names);%0A        
+    
 %7D%0A%0A        Compi
@@ -2249,32 +2249,36 @@
      %7D%0A%0A        
+  
+  
 Compiler compile
@@ -2306,24 +2306,28 @@
 Manifest);%0A%0A
+    
         Byte
@@ -2390,16 +2390,20 @@
         
+    
 compiler
@@ -2429,16 +2429,20 @@
         
+  
+  
 Path out
@@ -2531,55 +2531,277 @@
     
-Files.write(outFilePath, buffer.toByteArray());
+    if (args.length %3E 0) %7B%0A                outFilePath = Paths.get(args%5B0%5D);%0A            %7D%0A%0A            Files.write(outFilePath, buffer.toByteArray());%0A        %7D%0A        catch (IOException%7CClassNotFoundException e) %7B%0A            throw new RuntimeException(e);%0A        %7D
 %0A   

Refactor main to match required signature for main and use a set to remove duplicates from the list of classes to compile.