package com.turn.ttorrent.client;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SimpleClient {

  private final static int DEFAULT_EXECUTOR_SIZE = 10;
  private final CommunicationManager communicationManager;

  public SimpleClient() {
    this(DEFAULT_EXECUTOR_SIZE, DEFAULT_EXECUTOR_SIZE);
  }

  public SimpleClient(int workingExecutorSize, int validatorExecutorSize) {
    communicationManager = new CommunicationManager(Executors.newFixedThreadPool(workingExecutorSize), Executors.newFixedThreadPool(validatorExecutorSize));
  }

  public void stop() {
    stop(60, TimeUnit.SECONDS);
  }

  public void stop(int timeout, TimeUnit timeUnit) {
    communicationManager.stop(timeout, timeUnit);
    Exception interruptedException = null;
    boolean anyFailedByTimeout = false;
    for (ExecutorService executorService : Arrays.asList(
            communicationManager.getExecutor(),
            communicationManager.getPieceValidatorExecutor())) {
      executorService.shutdown();

      //if the thread is already interrupted don't try to await termination
      if (Thread.currentThread().isInterrupted()) continue;

      try {
        if (!executorService.awaitTermination(timeout, timeUnit)) {
          anyFailedByTimeout = true;
        }
      } catch (InterruptedException e) {
        interruptedException = e;
      }
    }
    if (interruptedException != null) {
      throw new RuntimeException("Thread was interrupted, " +
              "shutdown methods are invoked but maybe tasks are not finished yet", interruptedException);
    }
    if (anyFailedByTimeout)
      throw new RuntimeException("At least one executor was not fully shutdown because timeout was elapsed");

  }

  public void downloadTorrent(String torrentFile, String downloadDir, InetAddress iPv4Address) throws IOException, InterruptedException {
    TorrentManager torrentManager = startDownloading(torrentFile, downloadDir, iPv4Address);
    final Semaphore semaphore = new Semaphore(0);
    torrentManager.addListener(new TorrentListenerWrapper() {
      @Override
      public void downloadComplete() {
        semaphore.release();
      }
    });
    semaphore.acquire();
  }

  private TorrentManager startDownloading(String torrentFile, String downloadDir, InetAddress iPv4Address) throws IOException {
    communicationManager.start(iPv4Address);
    return communicationManager.addTorrent(torrentFile, downloadDir);
  }

  public TorrentManager downloadTorrentAsync(String torrentFile,
                              String downloadDir,
                              InetAddress iPv4Address) throws IOException {
    return startDownloading(torrentFile, downloadDir, iPv4Address);
  }
}

@@ -110,16 +110,69 @@
 Arrays;%0A
+import java.util.Collections;%0Aimport java.util.List;%0A
 import j
@@ -2103,83 +2103,35 @@
     
-TorrentManager torrent
+communication
 Manager
- = 
+.
 start
-Downloading(torrentFile, downloadDir, 
+(
 iPv4
@@ -2198,35 +2198,98 @@
     
-torrentManager.addListener(
+List%3CTorrentListener%3E listeners = Collections.%3CTorrentListener%3EsingletonList(%0A            
 new 
@@ -2311,24 +2311,33 @@
 Wrapper() %7B%0A
+%0A        
       @Overr
@@ -2340,16 +2340,215 @@
 verride%0A
+              public void validationComplete(int validpieces, int totalpieces) %7B%0A                if (validpieces == totalpieces) semaphore.release();%0A              %7D%0A%0A              @Override%0A        
       pu
@@ -2582,24 +2582,32 @@
 ) %7B%0A        
+       
+ 
 semaphore.re
@@ -2621,23 +2621,150 @@
 ;%0A      
-%7D%0A    %7D
+        %7D%0A            %7D%0A    );%0A    TorrentManager torrentManager = communicationManager.addTorrent(torrentFile, downloadDir, listeners
 );%0A    s
@@ -3131,16 +3131,31 @@
         
+               
 String d
@@ -3166,16 +3166,31 @@
 oadDir,%0A
+               
         

fix client hanging in "download torrent" method when torrent exists.