/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.tomcat.jdbc.test;

import java.sql.Connection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import org.junit.After;
import org.junit.Test;

import org.apache.tomcat.jdbc.pool.DataSourceProxy;
import org.apache.tomcat.jdbc.test.driver.Driver;

public class ConnectCountTest extends DefaultTestCase {

    protected boolean run = true;
    protected long sleep = Long.getLong("sleep", 10).longValue();
    protected long complete = Long.getLong("complete",20000).longValue();
    protected boolean printthread = Boolean.getBoolean("printthread");
    CountDownLatch latch = null;


    @Override
    public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
        // TODO Auto-generated method stub
        org.apache.tomcat.jdbc.pool.DataSource ds = super.createDefaultDataSource();
        ds.getPoolProperties().setDriverClassName(Driver.class.getName());
        ds.getPoolProperties().setUrl(Driver.url);
        ds.getPoolProperties().setInitialSize(0);
        ds.getPoolProperties().setMaxIdle(10);
        ds.getPoolProperties().setMinIdle(10);
        ds.getPoolProperties().setMaxActive(10);
        return ds;
    }


    @Override
    @After
    public void tearDown() throws Exception {
        Driver.reset();
        super.tearDown();
    }


    protected void printThreadResults(TestThread[] threads, String name, int active, int expected) {
        long minfetch = Long.MAX_VALUE, maxfetch = Long.MIN_VALUE, totalfetch = 0;
        long maxwait = 0, minwait = Long.MAX_VALUE, totalwait = 0;
        for (int i=0; i<threads.length; i++) {
            TestThread t = threads[i];
            totalfetch += t.nroffetch;
            totalwait  += t.totalwait;
            maxwait = Math.max(maxwait,t.maxwait);
            minwait = Math.min(minwait, t.minwait);
            minfetch = Math.min(minfetch, t.nroffetch);
            maxfetch = Math.max(maxfetch, t.nroffetch);
            if (ConnectCountTest.this.printthread)
                System.out.println(t.getName()+" : Nr-of-fetch:"+t.nroffetch+ " Max fetch Time:"+t.maxwait/1000000f+"ms. :Max close time:"+t.cmax/1000000f+"ms.");
        }
        System.out.println("["+name+"] Max fetch:"+(maxfetch)+" Min fetch:"+(minfetch)+" Average fetch:"+
                           (((float)totalfetch))/(float)threads.length);
        System.out.println("["+name+"] Max wait:"+maxwait/1000000f+"ms. Min wait:"+minwait/1000000f+"ms. Average wait:"+(((((float)totalwait))/(float)totalfetch)/1000000f)+" ms.");
        System.out.println("["+name+"] Max active:"+active+" Expected Active:"+expected);
    }

    @Test
    public void testDBCPThreads20Connections10() throws Exception {
        System.out.println("[testDBCPThreads20Connections10] Starting fairness - DBCP");
        this.threadcount = 20;
        this.transferProperties();
        this.tDatasource.getConnection().close();
        latch = new CountDownLatch(threadcount);
        long start = System.currentTimeMillis();
        TestThread[] threads = new TestThread[threadcount];
        for (int i=0; i<threadcount; i++) {
            threads[i] = new TestThread();
            threads[i].setName("tomcat-dbcp-"+i);
            threads[i].d = this.tDatasource;

        }
        for (int i=0; i<threadcount; i++) {
            threads[i].start();
        }
        if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
            System.out.println("Latch timed out.");
        }
        this.run = false;
        long delta = System.currentTimeMillis() - start;
        printThreadResults(threads,"testDBCPThreads20Connections10",Driver.connectCount.get(),10);
        System.out.println("Test completed in: " + delta + "ms.");
    }

    @Test
    public void testPoolThreads20Connections10() throws Exception {
        System.out.println("[testPoolThreads20Connections10] Starting fairness - Tomcat JDBC - Non Fair");
        this.threadcount = 20;
        this.transferProperties();
        this.datasource.getConnection().close();
        latch = new CountDownLatch(threadcount);
        long start = System.currentTimeMillis();
        TestThread[] threads = new TestThread[threadcount];
        for (int i=0; i<threadcount; i++) {
            threads[i] = new TestThread();
            threads[i].setName("tomcat-pool-"+i);
            threads[i].d = this.datasource;

        }
        for (int i=0; i<threadcount; i++) {
            threads[i].start();
        }
        if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
            System.out.println("Latch timed out.");
        }
        this.run = false;
        long delta = System.currentTimeMillis() - start;
        printThreadResults(threads,"testPoolThreads20Connections10",Driver.connectCount.get(),10);
        System.out.println("Test completed in: " + delta + "ms.");
    }

    @Test
    public void testPoolThreads20Connections10Fair() throws Exception {
        System.out.println("[testPoolThreads20Connections10Fair] Starting fairness - Tomcat JDBC - Fair");
        this.threadcount = 20;
        this.datasource.getPoolProperties().setFairQueue(true);
        this.transferProperties();
        this.datasource.getConnection().close();
        latch = new CountDownLatch(threadcount);
        long start = System.currentTimeMillis();
        TestThread[] threads = new TestThread[threadcount];
        for (int i=0; i<threadcount; i++) {
            threads[i] = new TestThread();
            threads[i].setName("tomcat-pool-"+i);
            threads[i].d = this.datasource;

        }
        for (int i=0; i<threadcount; i++) {
            threads[i].start();
        }
        if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
            System.out.println("Latch timed out.");
        }
        this.run = false;
        long delta = System.currentTimeMillis() - start;
        printThreadResults(threads,"testPoolThreads20Connections10Fair",Driver.connectCount.get(),10);
        System.out.println("Test completed in: " + delta + "ms.");
    }

    @Test
    public void testPoolThreads20Connections10FairAsync() throws Exception {
        System.out.println("[testPoolThreads20Connections10FairAsync] Starting fairness - Tomcat JDBC - Fair - Async");
        this.threadcount = 20;
        this.datasource.getPoolProperties().setFairQueue(true);
        this.datasource.getPoolProperties().setInitialSize(this.datasource.getPoolProperties().getMaxActive());
        this.transferProperties();
        this.datasource.getConnection().close();
        latch = new CountDownLatch(threadcount);
        long start = System.currentTimeMillis();
        TestThread[] threads = new TestThread[threadcount];
        for (int i=0; i<threadcount; i++) {
            threads[i] = new TestThread();
            threads[i].setName("tomcat-pool-"+i);
            threads[i].async = true;
            threads[i].d = this.datasource;

        }
        for (int i=0; i<threadcount; i++) {
            threads[i].start();
        }
        if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
            System.out.println("Latch timed out.");
        }
        this.run = false;
        long delta = System.currentTimeMillis() - start;
        printThreadResults(threads,"testPoolThreads20Connections10FairAsync",Driver.connectCount.get(),10);
        System.out.println("Test completed in: " + delta + "ms.");
    }

//    @Test
//    public void testC3P0Threads20Connections10() throws Exception {
//        System.out.println("[testC3P0Threads20Connections10] Starting fairness - C3P0");
//        this.threadcount = 20;
//        this.transferPropertiesToC3P0();
//        this.datasource.getConnection().close();
//        latch = new CountDownLatch(threadcount);
//        long start = System.currentTimeMillis();
//        TestThread[] threads = new TestThread[threadcount];
//        for (int i=0; i<threadcount; i++) {
//            threads[i] = new TestThread();
//            threads[i].setName("tomcat-pool-"+i);
//            threads[i].d = this.c3p0Datasource;
//
//        }
//        for (int i=0; i<threadcount; i++) {
//            threads[i].start();
//        }
//        if (!latch.await(complete+1000,TimeUnit.MILLISECONDS)) {
//            System.out.println("Latch timed out.");
//        }
//        this.run = false;
//        long delta = System.currentTimeMillis() - start;
//        printThreadResults(threads,"testC3P0Threads20Connections10",Driver.connectCount.get(),10);
//    }


    public class TestThread extends Thread {
        protected DataSource d;
        protected long sleep = 10;
        protected boolean async = false;
        long minwait = Long.MAX_VALUE, maxwait = -1, totalwait=0, totalcmax=0, cmax = -1, nroffetch = 0, totalruntime = 0;
        @Override
        public void run() {
            try {
                long now = System.currentTimeMillis();
                while (ConnectCountTest.this.run) {
                    if ((System.currentTimeMillis()-now)>=ConnectCountTest.this.complete) break;
                    long start = System.nanoTime();
                    Connection con = null;
                    try {
                        if (async) {
                            Future<Connection> cf = ((DataSourceProxy)d).getConnectionAsync();
                            con  = cf.get();
                        } else {
                            con = d.getConnection();
                        }
                        long delta = System.nanoTime() - start;
                        totalwait += delta;
                        maxwait = Math.max(delta, maxwait);
                        minwait = Math.min(delta, minwait);
                        nroffetch++;
                        try {
                            if (ConnectCountTest.this.sleep>0) sleep(ConnectCountTest.this.sleep);
                        } catch (InterruptedException x) {
                            interrupted();
                        }
                    } finally {
                        long cstart = System.nanoTime();
                        if (con!=null) try {con.close();}catch(Exception x) {x.printStackTrace();}
                        long cdelta = System.nanoTime() - cstart;
                        totalcmax += cdelta;
                        cmax = Math.max(cdelta, cmax);
                    }
                    totalruntime+=(System.nanoTime()-start);
                }

            } catch (Exception x) {
                x.printStackTrace();
            } finally {
                ConnectCountTest.this.latch.countDown();
            }
            if (System.getProperty("print-thread-stats")!=null) {
                System.out.println("["+getName()+"] "+
                    "\n\tMax time to retrieve connection:"+maxwait/1000000f+" ms."+
                    "\n\tTotal time to retrieve connection:"+totalwait/1000000f+" ms."+
                    "\n\tAverage time to retrieve connection:"+totalwait/1000000f/nroffetch+" ms."+
                    "\n\tMax time to close connection:"+cmax/1000000f+" ms."+
                    "\n\tTotal time to close connection:"+totalcmax/1000000f+" ms."+
                    "\n\tAverage time to close connection:"+totalcmax/1000000f/nroffetch+" ms."+
                    "\n\tRun time:"+totalruntime/1000000f+" ms."+
                    "\n\tNr of fetch:"+nroffetch);
            }
        }
    }
}
