/*
 ** 2015 December 01
 **
 ** The author disclaims copyright to this source code. In place of
 ** a legal notice, here is a blessing:
 **    May you do good and not evil.
 **    May you find forgiveness for yourself and forgive others.
 **    May you share freely, never taking more than you give.
 */
package info.ata4.disunity.cli.command.bundle;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import info.ata4.disunity.cli.command.FileCommand;
import info.ata4.disunity.cli.converters.PathConverter;
import info.ata4.io.util.PathUtils;
import info.ata4.junity.bundle.Bundle;
import info.ata4.junity.bundle.BundleReader;
import info.ata4.log.LogUtils;
import static info.ata4.util.function.IOConsumer.uncheck;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Nico Bergemann <barracuda415 at yahoo.de>
 */
@Parameters(
    commandDescription = "Extract files from bundles."
)
public class BundleUnpack extends FileCommand {

    private static final Logger L = LogUtils.getLogger();

    @Parameter(
        names = {"-o", "--output"},
        description = "Output directory",
        converter = PathConverter.class
    )
    private Path outputDir;

    @Parameter(
        names = {"-f", "--filename"},
        description = "Extract file with this name only."
    )
    private String filename;

    @Parameter(
        names = {"-p", "--prop"},
        description = "Write bundle property file."
    )
    private boolean writeProp;

    @Override
    protected void runFile(Path file) {
        try (BundleReader bundleReader = new BundleReader(file)) {
            Bundle bundle = bundleReader.read();

            AtomicInteger done = new AtomicInteger();
            long total = bundle.entryInfos().size();

            // define output directory, if not yet defined
            if (outputDir == null) {
                // if there's only one file inside the bundle, then don't bother
                // with sub-directories
                if (bundle.entryInfos().size() == 1) {
                    outputDir = file.getParent();
                } else {
                    String fileName = PathUtils.getBaseName(file);
                    outputDir = file.resolveSibling(fileName);
                }
            }

            try {
                bundle.entries()
                    .stream()
                    .filter(entry -> filename == null || entry.name().equals(filename))
                    .forEach(uncheck(entry -> {
                        progress.update(Optional.of(entry.name()), done.getAndIncrement() / (double) total);
                        Path entryFile = outputDir.resolve(entry.name());

                        Files.createDirectories(entryFile.getParent());
                        Files.copy(entry.inputStream(), entryFile, REPLACE_EXISTING);

                        if (done.get() == total) {
                            progress.update(Optional.empty(), 1);
                        }
                }));
            } catch (UncheckedIOException ex) {
                throw ex.getCause();
            }

            if (writeProp && filename == null) {
                String bundleName = outputDir.getFileName().toString();
                Path propsFile = outputDir.getParent().resolve(bundleName + ".json");
                BundleProps.write(propsFile, bundle);
            }
        } catch (IOException ex) {
            L.log(Level.WARNING, "Can't unpack asset bundle " + file, ex);
        }
    }
}

@@ -924,16 +924,45 @@
 XISTING;
+%0A%0Aimport java.nio.file.Paths;
 %0Aimport 
@@ -2393,24 +2393,221 @@
 etParent();%0A
+                    if (outputDir == null) %7B%0A                        // Passed a filename only. Use the current directory.%0A                        outputDir = Paths.get(%22.%22);%0A                    %7D%0A
             

Support bundle unpack with local file