package the8472.mldht.cli.commands;

import static the8472.bencode.Utils.buf2str;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;

import lbms.plugins.mldht.kad.DHT;
import lbms.plugins.mldht.kad.Key;
import lbms.plugins.mldht.kad.tasks.NodeLookup;
import the8472.mldht.cli.CommandProcessor;

public class Burst extends CommandProcessor {
	
	@Override
	protected void process() {
		Thread t = new Thread(() -> {
			int count = 50;
			
			if(arguments.size() > 0)
				count = Integer.parseInt(buf2str(ByteBuffer.wrap(arguments.get(0))));
			
			List<DHT> dhts = new ArrayList<>(this.dhts);
			
			List<CompletableFuture<Void>> futures = new ArrayList<>();
			
			for(int i=0;i<count;i++) {
				CompletableFuture<Void> future = new CompletableFuture<Void>();
				futures.add(future);
				DHT dht = dhts.get(ThreadLocalRandom.current().nextInt(dhts.size()));
				Optional.ofNullable(dht.getServerManager().getRandomActiveServer(false)).ifPresent(rpc -> {
					NodeLookup task = new NodeLookup(Key.createRandomKey(), rpc, dht.getNode(), false);
					task.addListener((finishedTask) -> {
						println("done: "+finishedTask+" ["+dht.getType()+"]");
						future.complete(null);
					});
					dht.getTaskManager().addTask(task);
				});
				
			}
			
			
			CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
			
			println("all done");
			
			exit(0);
		});
		
		t.setDaemon(true);
		t.setName("burst command");
		
		t.start();
	}


}

@@ -395,16 +395,58 @@
 Lookup;%0A
+import lbms.plugins.mldht.kad.tasks.Task;%0A
 import t
@@ -480,16 +480,16 @@
 cessor;%0A
-
 %0Apublic 
@@ -839,24 +839,76 @@
 ayList%3C%3E();%0A
+%09%09%09List%3CNodeLookup%3E tasks = new ArrayList%3C%3E(count);%0A
 %09%09%09%0A%09%09%09for(i
@@ -1277,24 +1277,46 @@
 (), false);%0A
+%09%09%09%09%09tasks.add(task);%0A
 %09%09%09%09%09task.ad
@@ -1341,24 +1341,152 @@
 dTask) -%3E %7B%0A
+%09%09%09%09%09%09if(!isRunning()) %7B%0A%09%09%09%09%09%09%09tasks.stream().filter(remaining -%3E !remaining.isFinished()).forEach(Task::kill);%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09%0A
 %09%09%09%09%09%09printl

abort burst command tasks when api link connection is lost