package test;

import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicLong;

public class Tester implements Runnable
{
  /**
   * number of requests to issue per session
   */
  public final static int requestCount = 32;

  /**
   * session item size multiplier used in kb
   * <p/>
   * max byte[] in the session will be 1024 * m * request-number
   */
  private final static int m = 2;

  private long n = 1024 * 1024 * requestCount;

  private final URL[] _urls;
  private final SessionStore _sessionStore;

  private AtomicLong _counter = new AtomicLong();
  private long _n = n;

  public Tester(URL[] urls, SessionStore sessionStore)
  {
    this._urls = urls;
    _sessionStore = sessionStore;
  }

  @Override
  public void run()
  {
    while (_counter.incrementAndGet() < _n) {

      long l = _counter.get();

      if (l % 10000 == 0)
        System.out.println(l);

      Session session = _sessionStore.next();
      if (session != null) {
        try {
          test(session);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }

  public void test(Session session) throws IOException
  {
    final int j = (int) (System.currentTimeMillis() % _urls.length);

    try {
      test(session, _urls[j]);
    } catch (ConnectException e) {

      int i = j + 1;

      if (i == _urls.length)
        i = 0;

      while (i != j) {
        try {
          test(session, _urls[i]);
          break;
        } catch (ConnectException ce) {

        }

        i++;

        if (i == _urls.length)
          i = 0;
      }

      if (i == j) {
        throw new IOException("all servers appear to be down");
      }
    }
  }

  public void test(Session session, URL url) throws IOException
  {
    HttpURLConnection http = (HttpURLConnection) url.openConnection();

    String sessionId = session.getSessionId();

    if (sessionId != null)
      http.setRequestProperty("Cookie", "JSESSIONID=" + session.getSessionId());

    http.setRequestProperty("request-number",
                            Integer.toString(session.getRequestCount()));

    http.setRequestProperty("size-multiplier", Integer.toString(m));

    http.connect();

    try {
      int responseCode = http.getResponseCode();

      byte[] buffer = new byte[1024];
      int l;

      if (responseCode == 200) {
        String cookie = http.getHeaderField("Set-Cookie");

        if (cookie != null)
          setSessionId(session, cookie);

        InputStream in = http.getInputStream();

        int sessionValueDelay = 0;

        while ((l = in.read(buffer)) > 0) {
          sessionValueDelay = Integer.parseInt(new String(buffer, 0, l));
        }

        if (sessionValueDelay > 1)
          System.out.println(session
                             + ", "
                             + session.getRequestCount()
                             + ", "
                             + sessionValueDelay);

        in.close();
      }
      else if (responseCode == 401) {
        _sessionStore.expire(session);
      }
      else {
        InputStream in = http.getErrorStream();

        while ((l = in.read(buffer)) > 0) ;

        in.close();
      }

      session.incrementRequestCount();
    } catch (Throwable t) {
      t.printStackTrace();
    } finally {
      if (session.getRequestCount() > session.getRequestCountMax())
        expire(session);

      session.resetInUse();

      http.disconnect();
    }
  }

  private void setSessionId(Session session, String cookie)
  {
    //Set-Cookie: JSESSIONID=aaanFzui3gP5_aD8Utbjv; path=/
    if (cookie == null)
      return;

    if (!cookie.startsWith("JSESSIONID="))
      throw new IllegalArgumentException();

    int z = cookie.indexOf(';');

    if (z == -1)
      z = cookie.length();

    String sessionId = cookie.substring(11, z);

    session.setSessionId(sessionId);
  }

  private void expire(Session session)
  {
    _sessionStore.expire(session);
  }
}

@@ -1279,19 +1279,13 @@
     
-final 
 int 
-j
+i
  = (
@@ -1343,173 +1343,53 @@
     
-try %7B%0A      test(session, _urls%5Bj%5D);%0A    %7D catch (ConnectException e) %7B%0A%0A      int i = j + 1;%0A%0A      if (i == _urls.length)%0A        i = 0;%0A%0A      while (i != j
+int l = 0;%0A%0A    while (l++ %3C _urls.length
 ) %7B%0A
-  
     
@@ -1396,34 +1396,32 @@
   try %7B%0A        
-  
 test(session, _u
@@ -1429,26 +1429,25 @@
 ls%5Bi%5D);%0A
-  
+%0A
         
 break;%0A 
@@ -1442,17 +1442,16 @@
     
-b
 re
-ak;%0A  
+turn;%0A
     
@@ -1487,31 +1487,27 @@
 e) %7B%0A%0A      
- 
- 
 %7D%0A%0A
-  
       i++;%0A%0A
@@ -1506,18 +1506,16 @@
   i++;%0A%0A
-  
       if
@@ -1543,18 +1543,16 @@
         
-  
 i = 0;%0A 
@@ -1558,61 +1558,32 @@
     
- 
- 
 %7D%0A%0A    
-  if (i == j) %7B%0A        throw new IOExceptio
+System.err.printl
 n(%22a
@@ -1614,33 +1614,40 @@
 down%22);%0A    
-  %7D%0A    %7D
+System.exit(-1);
 %0A  %7D%0A%0A  publ

refactor url select