package com.uniquepassive.mystery.util;

import com.google.common.base.Throwables;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class JarUtil {

    public static Map<String, ClassNode> parseJar(File targetJar)
            throws IOException {

        JarFile jarFile = new JarFile(targetJar);

        return jarFile.stream()
                .filter(e -> e.getName().toLowerCase().endsWith(".class"))
                .map(e -> {
                    try (InputStream classStream = jarFile.getInputStream(e)) {
                        ClassReader classReader = new ClassReader(classStream);
                        ClassNode classNode = new ClassNode();
                        classReader.accept(classNode, ClassReader.SKIP_FRAMES);
                        return classNode;
                    } catch (IOException ex) {
                        throw Throwables.propagate(ex);
                    }
                })
                .collect(Collectors.toMap(c -> c.name, Function.identity()));
    }

    public static void saveToFile(File targetJar, Collection<ClassNode> classes)
            throws IOException {

        try (ZipOutputStream zipFile = new ZipOutputStream(new FileOutputStream(targetJar))) {
            classes.forEach((c) -> {
                try {
                    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
                    c.accept(classWriter);
                    zipFile.putNextEntry(new ZipEntry(c.name + ".class"));
                    zipFile.write(classWriter.toByteArray());
                    zipFile.closeEntry();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            zipFile.closeEntry();
        }
    }
}

@@ -325,40 +325,9 @@
 til.
-Collection;%0Aimport java.util.Map
+*
 ;%0Aim
@@ -693,16 +693,33 @@
  jarFile
+%0A                
 .stream(
@@ -1504,32 +1504,306 @@
  IOException %7B%0A%0A
+        List%3CClassNode%3E classList = new ArrayList%3C%3E(classes);%0A%0A        /*%0A            Shuffle the class list%0A            so that the file order%0A            in the output jar isn't%0A            the same as the input order.%0A         */%0A        Collections.shuffle(classList);%0A%0A
         try (Zip
@@ -1898,18 +1898,20 @@
    class
-es
+List
 .forEach

Save classes to file in a random order