package ahlers.phantom.embedded;

import com.google.common.base.Optional;
import de.flapdoodle.embed.process.config.store.FileSet;
import de.flapdoodle.embed.process.config.store.FileType;
import de.flapdoodle.embed.process.config.store.IPackageResolver;
import de.flapdoodle.embed.process.distribution.ArchiveType;
import de.flapdoodle.embed.process.distribution.Distribution;

import static de.flapdoodle.embed.process.distribution.ArchiveType.TBZ2;
import static de.flapdoodle.embed.process.distribution.ArchiveType.ZIP;
import static de.flapdoodle.embed.process.distribution.Platform.Linux;
import static java.lang.String.format;

/**
 * Translates components of {@link Distribution} into literal components of PhantomJS's distributed files.
 *
 * @author [[mailto:michael@ahlers.consulting Michael Ahlers]]
 * @see <a href="http://phantomjs.org/download.html">PhantomJS: Download</a>
 */
public enum PhantomPackageResolver
        implements IPackageResolver {

    INSTANCE;

    public static PhantomPackageResolver getInstance() {
        return INSTANCE;
    }

    @Override
    public ArchiveType getArchiveType(final Distribution distribution) {
        switch (distribution.getPlatform()) {
            case Linux:
                return TBZ2;
            case OS_X:
            case Windows:
                return ZIP;
            default:
                throw new UnsupportedPlatformException(distribution);
        }
    }

    static String platformClassifierFor(final Distribution distribution) {
        switch (distribution.getPlatform()) {
            case Linux:
                return "linux";
            case OS_X:
                return "macosx";
            case Windows:
                return "windows";
            default:
                throw new UnsupportedPlatformException(distribution);
        }
    }

    static Optional<String> bitsizeClassifierFor(final Distribution distribution) {
        if (Linux == distribution.getPlatform()) {
            switch (distribution.getBitsize()) {
                case B32:
                    return Optional.of("i686");
                case B64:
                    return Optional.of("x86_64");
                default:
                    throw new UnsupportedBitsizeException(distribution);
            }
        } else {
            return Optional.absent();
        }
    }

    public static String archiveFilenameFor(final Distribution distribution) {
        final String version = distribution.getVersion().asInDownloadPath();
        final String platformClassifier = platformClassifierFor(distribution);
        final Optional<String> bitsizeClassifier = bitsizeClassifierFor(distribution);
        return String.format("phantomjs-%s-%s%s", version, platformClassifier, bitsizeClassifier.isPresent() ? "-" + bitsizeClassifier.get() : "");
    }

    public static String archiveExtensionFor(final Distribution distribution, final ArchiveType archiveType) {
        switch (archiveType) {
            case TBZ2:
                return "tar.bz2";
            case ZIP:
                return "zip";
            default:
                throw new UnsupportedArchiveException(distribution, archiveType);
        }
    }

    @Override
    public String getPath(final Distribution distribution) {
        final String filename = archiveFilenameFor(distribution);
        final String extension = archiveExtensionFor(distribution, getArchiveType(distribution));
        return String.format("%s.%s", filename, extension);
    }

    @Override
    public FileSet getFileSet(final Distribution distribution) {
        final FileSet.Builder builder = FileSet.builder();

        switch (distribution.getPlatform()) {
            case Linux:
            case OS_X:
                builder.addEntry(FileType.Executable, "phantomjs");
                break;
            case Windows:
                builder.addEntry(FileType.Executable, "phantomjs.exe");
                break;
            default:
                throw new UnsupportedPlatformException(distribution);
        }

        return builder.build();
    }
}

@@ -591,47 +591,8 @@
 nux;
-%0Aimport static java.lang.String.format;
 %0A%0A/*
@@ -1021,38 +1021,24 @@
 NCE;%0A    %7D%0A%0A
-    @Override%0A
     public A
@@ -1036,16 +1036,23 @@
  public 
+static 
 ArchiveT
@@ -1055,20 +1055,17 @@
 iveType 
-getA
+a
 rchiveTy
@@ -1066,16 +1066,19 @@
 hiveType
+For
 (final D
@@ -1364,32 +1364,32 @@
 (distribution);%0A
-
         %7D%0A    %7D%0A
@@ -1381,32 +1381,171 @@
        %7D%0A    %7D%0A%0A
+    @Override%0A    public ArchiveType getArchiveType(final Distribution distribution) %7B%0A        return archiveTypeFor(distribution);%0A    %7D%0A%0A
     static Strin
@@ -3000,17 +3000,27 @@
 ribution
-,
+) %7B%0A       
  final A
@@ -3033,35 +3033,65 @@
 Type archiveType
-) %7B
+ = archiveTypeFor(distribution);%0A
 %0A        switch 
@@ -3545,38 +3545,8 @@
 tion
-, getArchiveType(distribution)
 );%0A 

Simplify public API (for #17)