/*
 * Copyright (c) 2002, 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.s1peqe.connector.cci;

import java.math.BigDecimal;
import java.util.*;
import jakarta.ejb.*;
import jakarta.resource.cci.*;
import jakarta.resource.ResourceException;
import javax.naming.*;
import com.sun.connector.cciblackbox.*;

public class CoffeeBean implements SessionBean {

    private SessionContext sc;
    private String user;
    private String password;
    private ConnectionFactory cf;


    public void ejbCreate() throws CreateException {
    }

    public void setSessionContext(SessionContext sc) {
        try {
            this.sc = sc;
            Context ic = new InitialContext();
            user = (String) ic.lookup("java:comp/env/user");
            password = (String) ic.lookup("java:comp/env/password");
            cf = (jakarta.resource.cci.ConnectionFactory) ic.lookup("java:comp/env/eis/CCIEIS");
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
    }

    public int getCoffeeCount() {
        int count = -1;
        try {
            Connection con = getCCIConnection();
            Interaction ix = con.createInteraction();
            CciInteractionSpec iSpec = new CciInteractionSpec();
            iSpec.setSchema(user);
            iSpec.setCatalog(null);
            iSpec.setFunctionName("COUNTCOFFEE");
            RecordFactory rf = cf.getRecordFactory();
            IndexedRecord iRec = rf.createIndexedRecord("InputRecord");
            jakarta.resource.cci.Record oRec = ix.execute(iSpec, iRec);
            Iterator iterator = ((IndexedRecord)oRec).iterator();
            while(iterator.hasNext()) {
                Object obj = iterator.next();
                if(obj instanceof Integer) {
                    count = ((Integer)obj).intValue();
                }
                else if(obj instanceof BigDecimal) {
                    count = ((BigDecimal)obj).intValue();
                }
            }
            closeCCIConnection(con);
        }catch(ResourceException ex) {
            ex.printStackTrace();
        }
        return count;
    }


    public void insertCoffee(String name, int qty) {
        try {
            Connection con = getCCIConnection();
            Interaction ix = con.createInteraction();
            CciInteractionSpec iSpec = new CciInteractionSpec();
            iSpec.setFunctionName("INSERTCOFFEE");
            iSpec.setSchema(user);
            iSpec.setCatalog(null);
            RecordFactory rf = cf.getRecordFactory();
            IndexedRecord iRec = rf.createIndexedRecord("InputRecord");
            boolean flag = iRec.add(name);
            flag = iRec.add(new Integer(qty));
            ix.execute(iSpec, iRec);
            closeCCIConnection(con);
        }catch(ResourceException ex) {
            ex.printStackTrace();
        }
    }

    private Connection getCCIConnection() {
        Connection con = null;

    System.out.println("<========== IN get cci Connection ===========>");
        try {
            ConnectionSpec spec = new CciConnectionSpec("DBUSER", "DBPASSWORD");
    System.out.println("<========== Created ISpec ===========>");
    System.out.println("CF value : " + cf);
            con = cf.getConnection(spec);
        } catch (ResourceException ex) {
            ex.printStackTrace();
        }
        return con;
    }

    private void closeCCIConnection(Connection con) {
        try {
            con.close();
        } catch (ResourceException ex) {
            ex.printStackTrace();
        }
    }

    public void ejbRemove() {}
    public void ejbActivate() {}
    public void ejbPassivate() {}

}
