/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.s1asdev.jdbc.pooling.ejb;

import javax.ejb.*;
import javax.naming.*;
import javax.sql.*;
import java.rmi.*;
import java.util.*;
import java.sql.*;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

public class SimpleSessionBean implements SessionBean
{

    private SessionContext context;
    private static int count = 10;
    private static boolean rollback;
    private static String tableName = "COFFEE";
    private InitialContext ic;
    private DataSource ds;
    private DataSource xads; 
    private DataSource contds;
    private static boolean isXA=false;
    public void setSessionContext(SessionContext ctxt) {
        this.context = ctxt;
	try {
	    ic = new InitialContext();
	    ds = (DataSource)ic.lookup("java:comp/env/DataSource");
	    xads = (DataSource)ic.lookup("java:comp/env/XADataSource");
	    contds = (DataSource) ic.lookup("java:comp/env/ContainerDataSource");
	} catch( Exception ne ) {
	    ne.printStackTrace();
	}
    }

    public void ejbCreate() throws CreateException {
    }

    public boolean test1(boolean isXa, boolean rollback) {
	boolean passed = false;
	this.isXA = isXa;
	this.rollback = rollback;
	DataSource ds = null;
	if(isXA) {
	    ds = this.xads;
	} else {
	    ds = this.ds;
	}
        UserTransaction ut = null;
        try {
            
            createTable(ds);
            
            int count1 = getCount(ds);
            System.out.println("count1 : " + count1);
            
            ut = (UserTransaction) context.getUserTransaction();
            ut.begin();
            
            for(int i=0; i< count; i++)
                insertRow(ds);
            if(rollback)
                ut.rollback();
            else
                ut.commit();
            
            int count2=getCount(ds);
            
            System.out.println("count2 : " + count2);
            
            int diff = count2 - count1;
            if(( diff == count && !rollback) || (diff == 0 && rollback))
                passed = true;
            else
                passed = false;
            
        } catch(Exception e){
            passed = false;
            e.printStackTrace();
            if(ut != null){
                try {
                    ut.rollback();
                } catch (IllegalStateException ex) {
                    ex.printStackTrace();
                } catch (SecurityException ex) {
                    ex.printStackTrace();
                } catch (SystemException ex) {
                    ex.printStackTrace();
                }
            }
        };
	return passed;
        
    }
    
    public boolean test2(boolean isXa, boolean rollback) {
	boolean passed = false;
	this.isXA = isXa;
	this.rollback = rollback;
	DataSource ds = null;
	if(isXA) {
	    ds = this.xads;
	} else {
	    ds = this.ds;
	}
        UserTransaction ut = null;
        try {
            Connection[] con;

            createTable(ds);
            
            int count1 = getCount(ds);
            System.out.println("count1 : " + count1);
            
            ut = (UserTransaction) context.getUserTransaction();
            ut.begin();
            
            con = openConnections(ds, count);
            insertRow(con);
            closeConnections(con);
            
            if(rollback)
                ut.rollback();
            else
                ut.commit();
            
            int count2=getCount(ds);
            
            System.out.println("count2 : " + count2);
            
            int diff = count2 - count1;
            if(( diff == count && !rollback) || (diff == 0 && rollback))
                passed = true;
            else
                passed = false;
            
        } catch(Exception e){
            passed = false;
            e.printStackTrace();
            if(ut != null){
                try {
                    ut.rollback();
                } catch (IllegalStateException ex) {
                    ex.printStackTrace();
                } catch (SecurityException ex) {
                    ex.printStackTrace();
                } catch (SystemException ex) {
                    ex.printStackTrace();
                }
            }
        }
	return passed;
    }

    public boolean test3(boolean rollback) {
	boolean passed = false;
	this.rollback = rollback;
        UserTransaction ut = null;
	DataSource ds1 = this.ds;
	DataSource ds2 = this.xads;
        try {
            
            isXA = false;
            createTable(ds1);
            isXA = true;
            createTable(ds2);
            
            isXA = false;
            int count1 = getCount(ds1);
            isXA = true;
            int count3 = getCount(ds2);
            System.out.println("count1 : " + count1);
            System.out.println("count3 : " + count3);
            
            ut = (UserTransaction) context.getUserTransaction();
            ut.begin();
            
            isXA = false;
            for(int i=0; i< count; i++)
                insertRow(ds1);
            isXA = true;
            for(int i=0; i< count; i++)
                insertRow(ds2);
            
            if(rollback)
                ut.rollback();
            else
                ut.commit();
            
            isXA = false;
            int count2=getCount(ds1);
            isXA = true;
            int count4=getCount(ds2);
            
            System.out.println("count2 : " + count2);
            System.out.println("count4 : " + count4);
            
            int diff1 = count2 - count1;
            int diff2 = count4 - count3;
            if((( diff1 == count && !rollback) || (diff1 == 0 && rollback))
            && (( diff2 == count && !rollback) || (diff2 == 0 && rollback)))
                passed=true;
            else
                passed=false;
            
        } catch(Exception e){
            passed=false;
            e.printStackTrace();
            if(ut != null){
                try {
                    ut.rollback();
                } catch (IllegalStateException ex) {
                    ex.printStackTrace();
                } catch (SecurityException ex) {
                    ex.printStackTrace();
                } catch (SystemException ex) {
                    ex.printStackTrace();
                }
            }
        };
       return passed; 
    }
    
    private void createTable(final DataSource ds) throws SQLException {
        String tableName;
        if(isXA)
            tableName = "COFFEE_XA";
        else
            tableName = "COFFEE";
        
        Connection con;
        Statement stmt;
        con = ds.getConnection("scott", "tiger");
        stmt = con.createStatement();
        
        try{
            stmt.executeUpdate("drop table " + tableName);
        }catch(Exception ex){
            ex.printStackTrace();
        }
        stmt.executeUpdate("create table " + tableName + " (name varchar(32), qty integer)");
        stmt.close();
        con.close();
    }
    
    private int getCount(final DataSource ds) throws SQLException {
        String tableName;
        if(isXA)
            tableName = "COFFEE_XA";
        else
            tableName = "COFFEE";
        Statement stmt;
        Connection con;
        ResultSet rs;
        con = ds.getConnection("scott", "tiger");
        stmt = con.createStatement();
        rs = stmt.executeQuery( "SELECT count(*) FROM " + tableName);
        rs.next();
        int count = rs.getInt(1);
        rs.close();
        stmt.close();
        con.close();
        return count;
    }
    
    private void insertRow(final DataSource ds) throws SQLException {
        String tableName;
        if(isXA)
            tableName = "COFFEE_XA";
        else
            tableName = "COFFEE";
        Statement stmt;
        Connection con;
        con = ds.getConnection("scott", "tiger");
        stmt = con.createStatement();
        stmt.executeUpdate("INSERT INTO " + tableName + " values ('COFFEE', 100)");
        stmt.close();
        con.close();
    }
    
    private void insertRow(final Connection[] con) throws SQLException {
        String tableName;
        if(isXA)
            tableName = "COFFEE_XA";
        else
            tableName = "COFFEE";
        Statement stmt;
        for(int i=0; i < con.length; i++){
            stmt = con[i].createStatement();
            stmt.executeUpdate("INSERT INTO " + tableName + " values ('COFFEE', 100)");
	    stmt.close();
        }
    }
    
   
    private void printConnection(final DataSource ds) throws SQLException{
        com.sun.appserv.jdbc.DataSource dsTyped = (com.sun.appserv.jdbc.DataSource) ds;
        Connection wrapper = dsTyped.getConnection("scott", "tiger");
        System.out.println("Connection type : " + dsTyped.getConnection(wrapper));
        wrapper.close();
    }
    
    public boolean openAndCloseConnection(int count) {
	boolean status = true;
	DataSource ds = contds;

        try {
            com.sun.appserv.jdbc.DataSource dsTyped = (com.sun.appserv.jdbc.DataSource) ds;
	    HashSet<String> connections = new HashSet<String>();
            Connection con;
	    String conType;
	    int i = 0;
            for(; i < count; i++){
                con = ds.getConnection();
		conType = dsTyped.getConnection(con).toString();
        	System.out.println("Connection type : " + conType);
                con.close();
		if(!connections.add(conType)){
			status = false;
			break;
		}
            }
       	    System.out.println("Total connection requested :  " + count);
       	    System.out.println("Total connection created :  " + i);
       	    System.out.println("Total number of unique connection :  " + connections.size());
        }catch(Exception ex){
            ex.printStackTrace();
        }
	return status;
    }
    
    public boolean openMaxConnections(int count) {
	boolean status = false;
	DataSource ds = contds;
        Connection[] con = new Connection[count];
	int i = 0;
        for(; i < count; i++){
	   try{
           	con[i] = ds.getConnection();
	   }catch(SQLException ex){
		System.out.println("Unable to create max connections");
		status = false;
	   }
	}

	if(i ==  count){
		System.out.println("Able to create max connections");
		status=true;
		try{
			ds.getConnection();
                	System.out.println("Able to create beyond max connections");
                	status=false;
		}catch(SQLException ex){
                	System.out.println("Unable to create beyond max connections");
		        status=true;
           	}
	}
        
        for(; i > 0; i--){
	   try{
            	con[i - 1].close();
	   }catch(SQLException ex){
		System.out.println("Unable to close connection");
	   }
	}
	return status;
    }

    private Connection[] openConnections(DataSource ds, int count) throws NamingException, SQLException {
        
        Connection[] con = new Connection[count];
        for(int i=0; i < count; i++)
            con[i] = ds.getConnection("scott", "tiger");
        
        return con;
    }
    
    private void closeConnections(Connection[] con) throws SQLException {
        for(int i=0; i < count; i++)
            con[i].close();
    }
    
    public void ejbLoad() {}
    public void ejbStore() {}
    public void ejbRemove() {}
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void unsetEntityContext() {}
    public void ejbPostCreate() {}
}
