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

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

public class SimpleSessionBean implements SessionBean {

    private transient SessionContext ctxt_  = null;
    private InitialContext ic_;
    transient com.sun.appserv.jdbc.DataSource ds;

    public void setSessionContext(SessionContext context) {
        ctxt_ = context;
        try {
            ic_ = new InitialContext();
        } catch (NamingException ne) {
            ne.printStackTrace();
        }
    }

    public void ejbCreate() throws CreateException {
    }

    public boolean test1() throws Exception {
        Connection conn = null;
        Connection noTxConn = null;
        Statement stmt = null;
        Statement stmt2 = null;
        ResultSet rs = null;
        ResultSet rs2 = null;

        try {

            ds = (com.sun.appserv.jdbc.DataSource) ic_.lookup("java:comp/env/DataSource");

            UserTransaction tx =(UserTransaction)ctxt_.getUserTransaction();
              tx.begin();
            conn = ds.getConnection();
              noTxConn = ds.getNonTxConnection();
            stmt = conn.createStatement();
              stmt.executeUpdate("INSERT INTO NOTXCONNTABLE VALUES('method1',3)");
            String query1 = "SELECT * FROM NOTXCONNTABLE";
            rs = stmt.executeQuery(query1);
              stmt2 = noTxConn.createStatement();
            rs2 = stmt2.executeQuery("SELECT * FROM NOTXCONNTABLE");

            if ( rs2.next() ) {
                return false;
              }

              tx.commit();
              return true;

        } catch (Exception e) {
            System.out.println("Caught Exception---");
            e.printStackTrace();
            return false;
        } finally {
            if (rs != null ) {
                try { rs.close(); } catch( Exception e1) {}
            }
            if (stmt != null ) {
                try {stmt.close(); } catch( Exception e1) {}
            }
            if (conn != null ) {
                try {conn.close();} catch( Exception e1) {}
            }

            if (rs2 != null ) {
                try {rs2.close();} catch( Exception e1 ) {}
            }
            if (stmt2 != null ) {
                try {stmt2.close(); } catch( Exception e1) {}
            }

            if (noTxConn != null ) {
                try { noTxConn.close(); }catch( Exception e1) {}
            }
        }


    }

    public boolean test2() throws Exception {
        Connection conn = null;
        Connection noTxConn = null;

        try {

            ds = (com.sun.appserv.jdbc.DataSource)ic_.lookup("java:comp/env/DataSource");

            UserTransaction tx =(UserTransaction)ctxt_.getUserTransaction();
              tx.begin();
            System.out.println("Getting TRANSACTIONAL connection");
            conn = ds.getConnection();
            System.out.println("Autocommit => " + conn.getAutoCommit());

              if (conn.getAutoCommit() == true ) {
                  return false;
              }

              conn.close();
              for (int i = 0; i < 20; i++ ) {
                    System.out.println("Getting NonTx connection");
                  noTxConn = ((com.sun.appserv.jdbc.DataSource)ds).getNonTxConnection();
                      System.out.println("Autocommit => " + noTxConn.getAutoCommit());
                    if (noTxConn.getAutoCommit() == false ) {
                      return false;
                    }
                    noTxConn.close();
              }
            System.out.println("Getting TRANSACTIONAL connection");
            conn = ds.getConnection();
            System.out.println("Autocommit => " + conn.getAutoCommit());
              if (conn.getAutoCommit() == true ) {
                  return false;
              }
              conn.close();
              tx.commit();

              return true;

        } catch (Exception e) {
            System.out.println("Caught Exception---");
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (noTxConn != null ) {
                    noTxConn.close();
                }
            } catch( Exception e1 ) {}
        }


    }

    public void ejbLoad() {
    }

    public void ejbStore() {
    }

    public void ejbRemove() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void unsetEntityContext() {
    }

    public void ejbPostCreate() {
    }
}
