package org.svetovid.installer;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.svetovid.io.SvetovidProcess;
import org.svetovid.run.SvetovidProcessBuilder;

public final class JavaInstallation implements Comparable<JavaInstallation> {

    private Path location;
    private Path binLocation;
    private Path libLocation;

    private String jdkVersion;
    private String jreVersion;
    private String libVersion;

    private JavaInstallation() {
        this.location = null;
        String[] extdirs = System.getProperty("java.ext.dirs").split(File.pathSeparator);
        if (extdirs.length > 1) {
            libLocation = Paths.get(extdirs[1]);
        }
    }

    private JavaInstallation(Path location) {
        this.location = location;
        initialize();
    }

    @Override
    public int hashCode() {
        if (location == null) {
            return 0;
        }
        return location.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof JavaInstallation)) {
            return false;
        }
        Path thatLocation = ((JavaInstallation) obj).location;
        if (this.location == thatLocation) {
            return true;
        }
        if (this.location == null) {
            return false;
        }
        return this.location.equals(thatLocation);
    }

    @Override
    public int compareTo(JavaInstallation that) {
        if ((this.location == null) && (that.location == null)) {
            return 0;
        }
        if (this.location == null) {
            return -1;
        }
        if (that.location == null) {
            return 1;
        }
        return this.location.compareTo(that.location);
    }

    private void initialize() {
        if (location == null) {
            return;
        }
        binLocation = libLocation = null;
        jdkVersion = jreVersion = libVersion = null;
        if (!Files.isDirectory(location)) {
            return;
        }
        binLocation = location.resolve("bin");
        if (!Files.isDirectory(binLocation)) {
            return;
        }
        Path binary = binLocation.resolve("javac");
        SvetovidProcess process = exec(binLocation, binary.toString(), "-version");
        if (process != null) {
            jdkVersion = process.err.readLine();
            jdkVersion = jdkVersion.substring(jdkVersion.indexOf(' ') + 1);
        }
        binary = binLocation.resolve("java");
        process = exec(binLocation, binary.toString(), "-version");
        if (process != null) {
            jreVersion = process.err.readLine();
            jreVersion = jreVersion.substring(jreVersion.indexOf('"') + 1, jreVersion.length() - 1);
        }
        libLocation = location.resolve("jre/lib/ext");
        if (!Files.isDirectory(libLocation)) {
            libLocation = location.resolve("lib/ext");
        }
        if (!Files.isDirectory(libLocation)) {
            return;
        }
    }

    protected static SvetovidProcess exec(String... command) {
        return exec(null, command);
    }

    protected static SvetovidProcess exec(Path directory, String... command) {
        SvetovidProcessBuilder builder = new SvetovidProcessBuilder(directory, command);
        try {
            return builder.start();
        } catch (IOException e) {
            return null;
        }
    }

    public Path getLocation() {
        return location;
    }

    public Path getBinLocation() {
        return binLocation;
    }

    public Path getLibLocation() {
        return libLocation;
    }

    public String getJdkVersion() {
        return jdkVersion;
    }

    public String getJreVersion() {
        return jreVersion;
    }

    public String getLibVersion() {
        return libVersion;
    }
}

@@ -494,24 +494,94 @@
 ation%3E %7B%0D%0A%0D%0A
+    public static final String LIB_FILE_NAME = %22svetovid-lib.jar%22;%0D%0A%0D%0A
     private 
@@ -3424,32 +3424,844 @@
 rn;%0D%0A        %7D%0D%0A
+        Path libFile = libLocation.resolve(LIB_FILE_NAME);%0D%0A        if (!Files.isRegularFile(libFile)) %7B%0D%0A            return;%0D%0A        %7D%0D%0A        try %7B%0D%0A            ZipFile zip = new ZipFile(libFile.toString());%0D%0A            try %7B%0D%0A                ZipEntry entry = zip.getEntry(%22version.properties%22);%0D%0A                if (entry != null) %7B%0D%0A                    InputStream stream = zip.getInputStream(entry);%0D%0A                    Properties properties = new Properties();%0D%0A                    properties.load(stream);%0D%0A                    libVersion = properties.getProperty(%22version%22);%0D%0A                %7D%0D%0A            %7D finally %7B%0D%0A                zip.close();%0D%0A            %7D%0D%0A        %7D catch (ZipException e) %7B%0D%0A            // Do nothing%0D%0A        %7D catch (IOException e) %7B%0D%0A            // Do Nothing%0D%0A        %7D%0D%0A
     %7D%0D%0A%0D%0A    pro

Complete versioning of JavaInstallation