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

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

public class SimpleBMPBean implements EntityBean {

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

    private int[] columnIndexes6 = {2, 3};

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

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

    public boolean testHit() {
        System.out.println("Statement caching Hit test Start");
        com.sun.appserv.jdbc.DataSource ds = null;
        PreparedStatement stmt = null;
        PreparedStatement firstStatement = null;
        PreparedStatement lastStatement = null;
        String tableName = "customer_stmt_wrapper";
        ds = this.ds;
        int tableIndex = 1;
        boolean passed = false;
            Connection conn = null;
        try {
                conn = ds.getConnection();
                System.out.println(">>>> conn = " + conn.hashCode());
        }catch(Exception ex) {
        }
        for (int i = 1; i < 7; i++) {
            System.out.println("Index = " + i);
            try {

                if(i == 6) {
                    stmt = conn.prepareStatement("select * from "+ tableName + tableIndex + " where c_phone= ?");
                    lastStatement = stmt;
                    System.out.println("lastStatement : "  + lastStatement);
                } else {
                    int[] columnIndexes = {i+1, i+2};
                    stmt = conn.prepareStatement("select * from "+ tableName+i +" where c_phone= ?");
                }
                if(i == 1) {
                    firstStatement = stmt;
                    System.out.println("firstStatement : " + firstStatement);
                }
            } catch (Exception e) {
                e.printStackTrace();
                passed = false;
            } finally {
                if(stmt != null) {
                    try {
                        stmt.close();
                    } catch(Exception ex) {}
                }
            }
        }
        passed = (firstStatement == lastStatement);
        try {
            if(firstStatement != null) {
                firstStatement.close();
            }
            if(lastStatement != null) {
                lastStatement.close();
            }
        /*        if (conn != null) {
                    try {
                        conn.close();
                    } catch (Exception e1) {
                    }
                }*/
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Statement caching Hit test End");
        return passed;
    }

    public boolean testMiss() {
        System.out.println("Statement caching Hit after Miss test Start");
        com.sun.appserv.jdbc.DataSource ds = null;
        PreparedStatement stmt = null;
        PreparedStatement firstStatement = null;
        PreparedStatement lastStatement = null;
        String tableName = "customer_stmt_wrapper";
        ds = this.ds;
        int tableIndex = 1;

        Connection conn = null;
        try {
            conn = ds.getConnection();
                System.out.println(">>>> conn = " + conn.hashCode());
        } catch(Exception ex) {}
        boolean passed = false;
        for (int i = 1; i < 8; i++) {
            try {

                if(i == 6) {
                        //stmt = conn.prepareStatement("select * from " + tableName + tableIndex + " where c_phone=?");
                    stmt = conn.prepareStatement("select * from "+ tableName+i +" where c_phone= ?");
                    lastStatement = stmt;
                    System.out.println("lastStatement : "  + lastStatement);
                } else {
                    stmt = conn.prepareStatement("select * from "+ tableName+i +" where c_phone= ?");
                }
                if(i == 1) {
                    firstStatement = stmt;
                    System.out.println("firstStatement : " + firstStatement);
                }
            } catch (Exception e) {
                e.printStackTrace();
                passed = false;
            } finally {
            }
        }
        passed = firstStatement != lastStatement;
        try {
            if(firstStatement != null) {
                firstStatement.close();
            }
            if(lastStatement != null) {
                lastStatement.close();
            }
/*            if(conn != null) {
                conn.close();
            }*/
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Statement caching Hit after Miss test End");
        return passed;
    }


    public boolean testHitColumnNames() {
        System.out.println("Statement caching Hit (Column Names) test Start");
        com.sun.appserv.jdbc.DataSource ds = null;
        PreparedStatement stmt = null;
        PreparedStatement firstStatement = null;
        PreparedStatement lastStatement = null;
        String tableName = "customer_stmt_wrapper";
        ds = this.ds;
        int tableIndex = 1;
        boolean passed = false;
        Connection conn = null;
        try {
                conn = ds.getConnection();
                System.out.println(">>>> conn = " + conn.hashCode());
        }catch(Exception ex) {
        }
        for (int i = 1; i < 7; i++) {
            System.out.println("Index = " + i);
            try {

                if(i == 6) {
                    String[] columnNames = {"c_id", "c_phone"};
                    stmt = conn.prepareStatement("select * from "+ tableName + tableIndex + " where c_phone= ?", columnNames);
                    lastStatement = stmt;
                    System.out.println("lastStatement : "  + lastStatement);
                } else if(i ==1) {
                    String[] columnNames = {"c_id", "c_phone"};
                    stmt = conn.prepareStatement("select * from "+ tableName + tableIndex + " where c_phone= ?", columnNames);
                    firstStatement = stmt;
                    System.out.println("firstStatement : " + firstStatement);
                } else {
                    int j = i + 2;
                    int k = j + 1;
                    String[] columnNames = {"c_id"+j, "c_id"+k};
                    stmt = conn.prepareStatement("select * from "+ tableName+i +" where c_phone= ?", columnNames);
                }
            } catch (Exception e) {
                e.printStackTrace();
                passed = false;
            } finally {
                if(stmt != null) {
                    try {
                        stmt.close();
                    } catch(Exception ex) {}
                }
            }
        }
        passed = (firstStatement == lastStatement);
        try {
            if(firstStatement != null) {
                firstStatement.close();
            }
            if(lastStatement != null) {
                lastStatement.close();
            }
               /* if (conn != null) {
                    try {
                        conn.close();
                    } catch (Exception e1) {
                    }
                }*/
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Statement caching Hit (Column names) test End");
        return passed;
    }

    public boolean testHitColumnIndexes() {
        System.out.println("Statement caching Hit (Column indexes) test Start");
        com.sun.appserv.jdbc.DataSource ds = null;
        PreparedStatement stmt = null;
        PreparedStatement firstStatement = null;
        PreparedStatement lastStatement = null;
        String tableName = "customer_stmt_wrapper";
        ds = this.ds;
        int tableIndex = 1;
        boolean passed = false;
            Connection conn = null;
        try {
                conn = ds.getConnection();
                System.out.println(">>>> conn = " + conn.hashCode());
        }catch(Exception ex) {
        }
        for (int i = 1; i < 7; i++) {
            System.out.println("Index = " + i);
            try {

                if(i == 6) {
                    stmt = conn.prepareStatement("select * from "+ tableName + tableIndex + " where c_phone= ?", columnIndexes6);
                    lastStatement = stmt;
                    System.out.println("lastStatement : "  + lastStatement);
                } else {
                        //First stmt executed would have {2,3} same as columnIndexes6
                    int[] columnIndexes = {i+1, i+2};
                    stmt = conn.prepareStatement("select * from "+ tableName+i +" where c_phone= ?", columnIndexes);
                }
                if(i == 1) {
                    firstStatement = stmt;
                    System.out.println("firstStatement : " + firstStatement);
                }
            } catch (Exception e) {
                e.printStackTrace();
                passed = false;
            } finally {
                if(stmt != null) {
                    try {
                        stmt.close();
                    } catch(Exception ex) {}
                }
            }
        }
        passed = (firstStatement == lastStatement);
        try {
            if(firstStatement != null) {
                firstStatement.close();
            }
            if(lastStatement != null) {
                lastStatement.close();
            }
                /*if (conn != null) {
                    try {
                        conn.close();
                    } catch (Exception e1) {
                    }
                } */
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Statement caching Hit (Column indexes) test End");
        return passed;
    }
    public void ejbLoad() {
    }

    public void ejbStore() {
    }

    public void ejbRemove() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void unsetEntityContext() {
    }

    public void ejbPostCreate() {
    }
}
