package liebenberg.closure_utilities.javascript;


import com.google.common.base.Function;
import com.google.javascript.rhino.head.ScriptableObject;
import liebenberg.closure_utilities.internal.DependencyCalculator;
import liebenberg.closure_utilities.internal.DependencyException;
import liebenberg.closure_utilities.internal.SourceFileBase;
import liebenberg.closure_utilities.render.DependencyFileRenderer;
import liebenberg.closure_utilities.render.RenderException;
import liebenberg.closure_utilities.rhino.EnvJsRunner;
import liebenberg.closure_utilities.utilities.FS;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class ClosureRunner extends EnvJsRunner {

    private static final Function<File, ClosureSourceFile> TRANSFORM_FUNC =
            SourceFileBase.getTransformFunction(ClosureSourceFile.class);

    private static final ClosureImporter CLOSURE_IMPORTER =
            new ClosureImporter();

    private final Collection<File> sourceDirectories;

    private File baseFile;

    private Set<ClosureSourceFile> closureSourceFileSet = new HashSet<>();


    private static final ClosureDependencyParser parser =
            new ClosureDependencyParser();

    private DependencyCalculator<ClosureSourceFile> calculator;

    private static final DependencyFileRenderer dependencyFileRenderer =
            new DependencyFileRenderer();

    public ClosureRunner(@Nonnull Collection<File> sourceDirectories) {
        this.sourceDirectories = sourceDirectories;
    }

    private ClosureSourceFile parseSourceFile(File file) throws IOException {
        ClosureSourceFile closureSourceFile = new ClosureSourceFile(file);
        FileReader fileReader = new FileReader(file);
        parser.parse(closureSourceFile, fileReader);
        fileReader.close();
        return closureSourceFile;
    }

    private void scanDependencies() throws IOException {
        baseFile = null;
        closureSourceFileSet.clear();
        dependencyFileRenderer.reset();
        for (File sourceFile : FS.find(sourceDirectories, "js")) {
            ClosureSourceFile closureSourceFile = parseSourceFile(sourceFile);
            closureSourceFileSet.add(closureSourceFile);
            if (closureSourceFile.getIsBaseFile()) {
                baseFile = sourceFile;
            }
        }
        dependencyFileRenderer.setBasePath(baseFile.getParentFile()
                .getAbsolutePath());
        dependencyFileRenderer.setDependencies(closureSourceFileSet);
        calculator = new DependencyCalculator<>(closureSourceFileSet);
    }


    public void initialize() {
        super.initialize();
        try {
            scanDependencies();
            File baseDirectory = baseFile.getParentFile();
            ScriptableObject.putProperty(scope, "CLOSURE_BASE_PATH",
                    baseDirectory.getPath() + "/");
            ScriptableObject.putProperty(scope, "CLOSURE_IMPORT_SCRIPT",
                    CLOSURE_IMPORTER);
            evaluateFile(baseFile);
            evaluateString(dependencyFileRenderer.render());
        } catch (IOException | RenderException exception) {
            throw new RuntimeException(exception);
        }
    }

    public void require(String require)
            throws DependencyException, IOException {
        evaluateString("goog.require('" + require + "')");
    }
}

@@ -66,153 +66,46 @@
 gle.
-common.base.Function;%0Aimport com.google.javascript.rhino.head.ScriptableObject;%0Aimport liebenberg.closure_utilities.internal.DependencyCalculator
+javascript.rhino.head.ScriptableObject
 ;%0Aim
@@ -172,69 +172,8 @@
 on;%0A
-import liebenberg.closure_utilities.internal.SourceFileBase;%0A
 impo
@@ -642,159 +642,8 @@
  %7B%0A%0A
-    private static final Function%3CFile, ClosureSourceFile%3E TRANSFORM_FUNC =%0A            SourceFileBase.getTransformFunction(ClosureSourceFile.class);%0A%0A
     
@@ -1000,73 +1000,8 @@
 );%0A%0A
-    private DependencyCalculator%3CClosureSourceFile%3E calculator;%0A%0A
     
@@ -2230,79 +2230,8 @@
 t);%0A
-        calculator = new DependencyCalculator%3C%3E(closureSourceFileSet);%0A
     
@@ -2942,32 +2942,32 @@
 , IOException %7B%0A
-
         evaluate
@@ -3005,16 +3005,17 @@
 re + %22')
+;
 %22);%0A    

remove unused references