package peergos.server.tests.slow;

import org.junit.*;
import org.junit.runner.*;
import org.junit.runners.*;
import peergos.server.*;
import peergos.server.corenode.*;
import peergos.server.storage.*;
import peergos.server.util.Args;
import peergos.shared.*;
import peergos.shared.corenode.*;
import peergos.shared.storage.*;
import peergos.shared.user.*;
import peergos.shared.user.fs.*;

import java.net.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.*;

@RunWith(Parameterized.class)
public class MkdirSpeed {

    private static int RANDOM_SEED = 666;
    private final NetworkAccess network;
    private final Crypto crypto = Crypto.initJava();

    private static Random random = new Random(RANDOM_SEED);

    public MkdirSpeed(String useIPFS, Random r) throws Exception {
        this.network = buildHttpNetworkAccess(useIPFS.equals("IPFS"), r);
    }

    private static NetworkAccess buildHttpNetworkAccess(boolean useIpfs, Random r) throws Exception {
        int portMin = 9000;
        int portRange = 2000;
        int webPort = portMin + r.nextInt(portRange);
        int corePort = portMin + portRange + r.nextInt(portRange);
        Args args = Args.parse(new String[]{"useIPFS", "" + useIpfs, "-port", Integer.toString(webPort), "-corenodePort", Integer.toString(corePort)});
        Main.PKI_INIT.main(args);
        return NetworkAccess.buildJava(new URL("http://localhost:" + webPort)).get();
    }

    @Parameterized.Parameters()
    public static Collection<Object[]> parameters() {
        return Arrays.asList(new Object[][] {
//                {true, "IPFS", new Random(0)}
                {true, "NOTIPFS", new Random(0)}
        });
    }

    private String generateUsername() {
        return "test" + (random.nextInt() % 10000);
    }

    public static UserContext ensureSignedUp(String username, String password, NetworkAccess network, Crypto crypto) throws Exception {
        return UserContext.ensureSignedUp(username, password, network, crypto).get();
    }

    // (0 - 100 mkdirs)
    // All ram, not http =>  40 -   54 ms
    // All ram, http     => 400 -  416 ms
    // IPFS, http        => 660 -  840 ms
    @Test
    public void hugeFolder() throws Exception {
        String username = generateUsername();
        String password = "test01";
        UserContext context = ensureSignedUp(username, password, network, crypto);
        FileWrapper userRoot = context.getUserRoot().get();
        List<String> names = new ArrayList<>();
        IntStream.range(0, 100).forEach(i -> names.add(randomString()));

        long worst = 0, best = Long.MAX_VALUE, start = System.currentTimeMillis();
        for (int i=0; i < names.size(); i++) {
            String filename = names.get(i);
            long t1 = System.currentTimeMillis();
            userRoot.mkdir(filename, context.network, false, crypto.random, crypto.hasher).get();
            long duration = System.currentTimeMillis() - t1;
            worst = Math.max(worst, duration);
            best = Math.min(best, duration);
            System.err.printf("MKDIR(%d) duration: %d mS, best: %d mS, worst: %d mS, av: %d mS\n", i, duration, best, worst, (t1 + duration - start) / (i + 1));
        }
    }

    private static String randomString() {
        return UUID.randomUUID().toString();
    }
}

@@ -155,49 +155,13 @@
 ver.
-corenode.*;%0Aimport peergos.server.storage
+tests
 .*;%0A
@@ -222,75 +222,8 @@
 .*;%0A
-import peergos.shared.corenode.*;%0Aimport peergos.shared.storage.*;%0A
 impo
@@ -305,32 +305,8 @@
 .*;%0A
-import java.nio.file.*;%0A
 impo
@@ -866,328 +866,70 @@
     
-int portMin = 9000;%0A        int portRange = 2000;%0A        int webPort = portMin + r.nextInt(portRange);%0A        int corePort = portMin + portRange + r.nextInt(portRange);%0A        Args args = Args.parse(new String%5B%5D%7B%22useIPFS%22, %22%22 + useIpfs, %22-port%22, Integer.toString(webPort), %22-corenodePort%22, Integer.toString(corePort)%7D
+Args args = UserTests.buildArgs().with(%22useIPFS%22, %22%22 + useIpfs
 );%0A 
@@ -1034,15 +1034,27 @@
 %22 + 
-webP
+args.getInt(%22p
 ort
+%22)
 )).g
@@ -1217,22 +1217,16 @@
        %7B
-true, 
 %22IPFS%22, 
@@ -1261,14 +1261,8 @@
    %7B
-true, 
 %22NOT
@@ -1776,24 +1776,127 @@
 0 -  840 ms%0A
+    //%0A    // current baseline: MKDIR(99) duration: 1106 mS, best: 867 mS, worst: 1467 mS, av: 1063 mS%0A
     @Test%0A  
@@ -2523,16 +2523,27 @@
         
+ userRoot =
  userRoo
@@ -2614,19 +2614,20 @@
 hasher).
-get
+join
 ();%0A    

Fix mkdir benchmark