/*
 * Copyright (c) 2017, 2020 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.jdbcjmsauth.ejb;

import jakarta.ejb.SessionBean;
import jakarta.ejb.SessionContext;
import jakarta.ejb.CreateException;
import jakarta.jms.QueueConnectionFactory;
import jakarta.jms.QueueConnection;
import jakarta.jms.QueueSession;
import jakarta.jms.Session;
import javax.naming.InitialContext;

public class JmsAuthBean implements SessionBean {

    private SessionContext ctxt_;
    private QueueConnectionFactory qcf_;
    private QueueConnectionFactory qcf1_;

    public void ejbCreate() throws CreateException {
        try {
            InitialContext ic = new InitialContext();
            qcf_ = (QueueConnectionFactory)
                ic.lookup("java:comp/env/jms/MyQueueConnectionFactory");
            qcf1_ = (QueueConnectionFactory)
                ic.lookup("java:comp/env/jms/MyQueueConnectionFactory_CM");
        } catch( Exception e ) {
            e.printStackTrace();
            CreateException ce = new CreateException( e.getMessage() );
            ce.initCause( e );
            throw ce;
        }

    }

    public void ejbRemove() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void setSessionContext( SessionContext ctxt ) {
        ctxt_ = ctxt;
    }

    public boolean test1() {
        //application auth - getConnection w/ user/pass - must pass
        boolean passed = true;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf_.createQueueConnection("guest", "guest");
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 1--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = false;
        } finally {
            try {
                session.close();
                con.close();

            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test2() {
        //application auth - getConnection w/o user/pass - must fail
        boolean passed = true;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf_.createQueueConnection();
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 2--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = false;
        } finally {
            try {
                session.close();
                con.close();
            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test3() {
        //application auth - getConnection w/ wrong user/pass - must fail
        boolean passed = false;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf_.createQueueConnection("xyz", "xyz");
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 3--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = true;
        } finally {
            try {
                session.close();
                con.close();
            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test4() {
        //application auth - getConnection w/ correct user/pass
        //and then wrong - must pass
        boolean passed = false;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf_.createQueueConnection("guest", "guest");
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 4--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            return passed;
        } finally {
            try {
                session.close();
                con.close();
            } catch( Exception e ) {}
        }

        try {
            con = qcf_.createQueueConnection("xyz", "xyz" );
            session = con.createQueueSession( true, Session.AUTO_ACKNOWLEDGE );
        } catch( Exception e ) {
            System.out.println("------------jms test 4--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = true;
        } finally {
            try {
                session.close();
                con.close();
            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test5() {
        //container auth - getConnection w/o user/pass - must pass
        boolean passed = true;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf1_.createQueueConnection();
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 5--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = false;
        } finally {
            try {
                session.close();
                con.close();

            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test6() {
        //container auth - getConnection w/ user/pass - must pass
        boolean passed = true;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf1_.createQueueConnection("guest","guest");
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 6--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = false;
        } finally {
            try {
                session.close();
                con.close();

            } catch( Exception e ) {}
        }

        return passed;
    }

    public boolean test7() {
        //container auth - getConnection w/ wrong user/pass - must fail
        boolean passed = false;
        QueueConnection con = null;
        QueueSession session = null;

        try {
            con = qcf1_.createQueueConnection("xyz", "xyz");
            session = con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        } catch( Exception e ) {
            System.out.println("------------jms test 7--------------");
            e.printStackTrace();
            System.out.println("------------------------------------");
            passed = true;
        } finally {
            try {
                session.close();
                con.close();

            } catch( Exception e ) {}
        }

        return passed;
    }
}
