/*
 * 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.maxconnectionusage.ejb;

import javax.ejb.*;
import javax.naming.*;
import java.sql.*;

public class SimpleBMPBean implements EntityBean {

    protected com.sun.appserv.jdbc.DataSource ds;
    protected com.sun.appserv.jdbc.DataSource xads;

    public void setEntityContext(EntityContext entityContext) {
        Context context = null;
        try {
            context = new InitialContext();
            ds = (com.sun.appserv.jdbc.DataSource) context.lookup("java:comp/env/DataSource");
            xads = (com.sun.appserv.jdbc.DataSource) context.lookup("java:comp/env/XADataSource");
        } catch (NamingException e) {
            throw new EJBException("cant find datasource");
        }
    }

    public Integer ejbCreate() throws CreateException {
        return new Integer(1);
    }

    /**
     * Acquire 11 connections (assumption : maxconnectionusage property value is 10)<br>
     * With ConnectionSharing ON, Tx attribute "NotSupported" on this method, DataSource of type<br>
     * "javax.sql.DataSource" or "javax.sql.XADataSource" physical connections con-1 & con-11<br>
     * must be different. If they are different test is passed.<br>
     *
     * @return boolean
     */
    public boolean test1(boolean useXA) {
        Connection firstConnection = null;
        Connection lastConnection = null;
        com.sun.appserv.jdbc.DataSource ds = null;

        if (useXA) {
            ds = this.xads;
        } else {
            ds = this.ds;
        }

        boolean passed = false;
        for (int i = 0; i < 11; i++) {
            Connection conn = null;
            try {
                conn = ds.getConnection();
                System.out.println(ds.getConnection(conn));

                if (i == 0) {
                    firstConnection = ds.getConnection(conn);
                } else if (i == 10) {
                    lastConnection = ds.getConnection(conn);
                    //This is necessary for the last connection to
                    //make sure subsequent tests pass.
                    ds.markConnectionAsBad(conn);
                }
                passed = (firstConnection != lastConnection);

            } catch (Exception e) {
                e.printStackTrace();
                passed = false;
            } finally {
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (Exception e1) {
                    }
                }
            }
        }
        return passed;
    }


    public String test2(boolean useXA, int value) {
        Connection physicalConnection = null;
        Connection conn = null;
        Statement stmt = null;
        String physicalConnectionString = null;
        com.sun.appserv.jdbc.DataSource ds = null;

        if (useXA) {
            ds = this.xads;
        } else {
            ds = this.ds;
        }

        try {
            conn = ds.getConnection();
            stmt = conn.createStatement();
            stmt.executeUpdate("insert into max_connection_usage values (" + value + ",'" + value + "')");
            physicalConnection = ds.getConnection(conn);
            physicalConnectionString = physicalConnection.toString();

        } catch (Exception e) {
            physicalConnection = null;
            return null;
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (Exception e) {
            }
            if (conn != null) {
                try {
                    //System.out.println("Closing Connection : " + conn);
                    conn.close();
                } catch (Exception e1) {
                }
            }
        }

        return physicalConnectionString;
    }

    public String test3(int count, boolean useXA, int value) {
        Connection physicalConnection = null;
        Connection conn = null;
        Statement stmt = null;
        ResultSet set = null;

        com.sun.appserv.jdbc.DataSource ds = null;

        if (useXA) {
            ds = this.xads;
        } else {
            ds = this.ds;
        }

        try {
            conn = ds.getConnection();
            stmt = conn.createStatement();
            set = stmt.executeQuery("select count(*) as COUNT from max_connection_usage where id=" + value);
            while (set.next()) {
                int resultCount = set.getInt("COUNT");
                //System.out.println("Expected count ["+count+"] & Actual count ["+ resultCount +"]" );
                if (count == resultCount) {
                    physicalConnection = ds.getConnection(conn);
                } else {
                    System.out.println("Expected count [" + count + "] does not match [" + resultCount + "]");
                    break;
                }
            }

        } catch (Exception e) {
            physicalConnection = null;
            return null;
        } finally {
            try {
                if (set != null) {
                    set.close();
                }
            } catch (Exception e) {
            }
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (Exception e) {
            }
            if (conn != null) {
                try {
                    //System.out.println("Closing Connection : " + conn);
                    conn.close();
                } catch (Exception e1) {
                }
            }
        }

        return physicalConnection.toString();
    }

    public void ejbLoad() {
    }

    public void ejbStore() {
    }

    public void ejbRemove() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void unsetEntityContext() {
    }

    public void ejbPostCreate() {
    }
}
