package chanjarster.tomcat.valves;

import java.io.IOException;
import java.net.URI;
import java.net.UnknownHostException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

import org.apache.catalina.Context;
import org.apache.catalina.Valve;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.catalina.valves.AccessLogValve;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.junit.Test;

import com.mongodb.DB;
import com.mongodb.MongoClient;

public class MongoLogBenchmark extends TomcatBaseTest {


  private StringBuilder sb;
  
  @Override
  public void setUp() throws Exception {
    super.setUp();
    Tomcat tomcat = getTomcatInstance();
    
    Context ctx = tomcat.addContext("", getTemporaryDirectory().getAbsolutePath());
    Tomcat.addServlet(ctx, "servlet", new HttpServlet() {
      private static final long serialVersionUID = 1L;
      
      @Override
      public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        req.getParameterNames();
        res.setContentType("text/plain; charset=ISO-8859-1");
        res.getWriter().write("OK");
      }
      
    });
    ctx.addServletMapping("/", "servlet");
    
    /*
     * prepare MongoAccessLogValve
     */
    String host = "localhost";
    int port = 27017;
    String dbName = "test_logs";
    String collName = "tomcat_access_logs";
    
    // drop existed collection
    MongoClient mongoClient = null;
    DB db = null;
    try {
      mongoClient = new MongoClient(host, port);
      db = mongoClient.getDB(dbName);
      db.getCollection(collName).drop();
    } catch (UnknownHostException ex) {
      
    }
    
    MongoAccessLogValve mavl = new MongoAccessLogValve();
    mavl.setHost(host);
    mavl.setPort(port);
    mavl.setDbName(dbName);
    mavl.setCollName(collName);
    mavl.setPattern("default");
    
    // remove AccessLogValve
    for (Valve vl : tomcat.getHost().getPipeline().getValves()) {
      if (vl.getClass().equals(AccessLogValve.class)) {
        tomcat.getHost().getPipeline().removeValve(vl);
      }
    }
    
    tomcat.getHost().getPipeline().addValve(mavl);
    
    this.sb = new StringBuilder();
  }
  

  @Override
  public void tearDown() throws Exception {
    super.tearDown();
    System.out.println(sb.toString());
    sb = null;
  }
  
  @Test
  public void testMongoAccessLogValve() throws Exception {
    Tomcat tomcat = getTomcatInstance();
    tomcat.start();
    
    CloseableHttpClient httpclient = HttpClients.createDefault();
    String uri = "http://localhost:" + tomcat.getConnector().getLocalPort() + "/";
    HttpUriRequest post = RequestBuilder.post()
        .setUri(new URI(uri))
        .addParameter("IDToken1", "username")
        .addParameter("IDToken2", "password")
        .addParameter("IDToken3", "password")
        .addParameter("IDToken4", "password")
        .addParameter("IDToken5", "password")
        .build();
    

    int[] iterationsArray = {1000};

    for(int iterations : iterationsArray) {
      long start = System.currentTimeMillis();
      for (int i = 0; i < iterations; i++) {
        doRequest(httpclient, post);
      }
      long end = System.currentTimeMillis();
      sb.append(iterations + " iterations using MongoAccessLogValve took " + (end - start) + "ms").append("\n");
    }
    
  }

  private void doRequest(CloseableHttpClient httpclient, HttpUriRequest post) throws ClientProtocolException, IOException {
    httpclient.execute(post).close();
  }
  
}

@@ -115,16 +115,41 @@
 ception;
+%0Aimport java.util.Random;
 %0A%0Aimport
@@ -2933,455 +2933,299 @@
     
-String uri = %22http://localhost:%22 + tomcat.getConnector().getLocalPort() + %22/%22;%0A    HttpUriRequest post = RequestBuilder.post()
+%0A    int%5B%5D iterationsArray = %7B100%7D;
 %0A    
+%0A
     
-.setUri(new URI(uri))%0A        .addParameter(%22IDToken1%22, %22username%22)%0A        .addParameter(%22IDToken2%22, %22password%22)%0A        .addParameter(%22IDToken3%22, %22password%22)%0A        .addParameter(%22IDToken4%22, %22password%22)%0A        .addParameter(%22IDToken5%22, %22password%22)%0A        .build()
+String%5B%5D uris = %7B%22/%22, %22/abc%22, %22/sdefe%22, %22wefew%22%7D;%0A    String%5B%5D paramNames = %7B%22student.id%22, %22lesson.id%22, %22course.name%22, %22course.code%22%7D;%0A    String%5B%5D paramValues = %7B%221212%22, %2212D00A%22, %22870102%22, %22322344%22, %222344545%22%7D
 ;%0A    %0A
-%0A
     
-int%5B%5D iterationsArray = %7B1000%7D;%0A
+Random r = new Random();
 %0A   
@@ -3353,24 +3353,378 @@
 ons; i++) %7B%0A
+        String uri = %22http://localhost:%22 + tomcat.getConnector().getLocalPort() + uris%5Br.nextInt(4)%5D;%0A        RequestBuilder rb = RequestBuilder.post().setUri(new URI(uri));%0A        for(int j = 0; j %3C r.nextInt(4); j++) %7B%0A          rb.addParameter(paramNames%5Br.nextInt(4)%5D, paramValues%5Br.nextInt(4)%5D);%0A        %7D%0A        HttpUriRequest post = rb.build();%0A
         doRe

add random test