package meerkat.bulletinboard;

import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer;
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider;
import meerkat.bulletinboard.sqlserver.H2QueryProvider;
import meerkat.comm.CommunicationException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.sql.*;
import java.util.List;

import static org.junit.Assert.fail;

/**
 * Created by Arbel Deutsch Peled on 07-Dec-15.
 */
public class H2BulletinBoardServerTest {

    private final String dbName = "meerkatTest";

    private GenericBulletinBoardServerTest serverTest;

    private SQLQueryProvider queryProvider;

    private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests

    @Before
    public void init(){

        System.err.println("Starting to initialize H2BulletinBoardServerTest");
        long start = threadBean.getCurrentThreadCpuTime();

        queryProvider = new H2QueryProvider(dbName);

        try {

            Connection conn = queryProvider.getDataSource().getConnection();
            Statement stmt = conn.createStatement();

            List<String> deletionQueries = queryProvider.getSchemaDeletionCommands();

            for (String deletionQuery : deletionQueries) {
                stmt.execute(deletionQuery);
            }

        } catch (SQLException e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        BulletinBoardServer bulletinBoardServer = new BulletinBoardSQLServer(queryProvider);
        try {
            bulletinBoardServer.init();

        } catch (CommunicationException e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
            return;
        }

        serverTest = new GenericBulletinBoardServerTest();
        try {
            serverTest.init(bulletinBoardServer);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        long end = threadBean.getCurrentThreadCpuTime();
        System.err.println("Finished initializing H2BulletinBoardServerTest");
        System.err.println("Time of operation: " + (end - start));
    }

    @Test
    public void bulkTest() {
        System.err.println("Starting bulkTest of H2BulletinBoardServerTest");
        long start = threadBean.getCurrentThreadCpuTime();

        try {
            serverTest.testInsert();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        try{
            serverTest.testSimpleTagAndSignature();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        try{
            serverTest.testEnhancedTagsAndSignatures();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        long end = threadBean.getCurrentThreadCpuTime();
        System.err.println("Finished bulkTest of H2BulletinBoardServerTest");
        System.err.println("Time of operation: " + (end - start));
    }

    @Test
    public void testBatch() {

        final int BATCH_NUM = 20;

        try{
            for (int i = 0 ; i < BATCH_NUM ; i++) {
                serverTest.testPostBatch();
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

        try{
            serverTest.testReadBatch();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }

    }

    @Test
    public void testSyncQuery() {
        try {
            serverTest.testSyncQuery();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            fail(e.getMessage());
        }
    }

    @After
    public void close() {
        System.err.println("Starting to close H2BulletinBoardServerTest");
        long start = threadBean.getCurrentThreadCpuTime();

        serverTest.close();

        long end = threadBean.getCurrentThreadCpuTime();
        System.err.println("Finished closing H2BulletinBoardServerTest");
        System.err.println("Time of operation: " + (end - start));
    }

}
