// OrderPlacementSLR.java
// Stateless Session bean

package org.objectweb.jonas.stests.appli;

import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Vector;

import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;


/**
 *
 */
public class OrderPlacementSLR implements SessionBean {

    static private Logger logger = null;
    private transient SessionContext ctx;

    // ------------------------------------------------------------------
    // SessionBean implementation
    // ------------------------------------------------------------------


    public void setSessionContext(SessionContext ctxt) {
        if (logger == null) {
            logger = Log.getLogger("org.objectweb.jonas_tests");
        }
        logger.log(BasicLevel.DEBUG, "");
        ctx = ctxt;
    }
        

    public void ejbRemove() {
        logger.log(BasicLevel.DEBUG, "");
    }
        

    public void ejbCreate() throws CreateException {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbPassivate() {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbActivate() {
        logger.log(BasicLevel.DEBUG, "");
    }
    
    // ------------------------------------------------------------------
    // OrderPlacement implementation
    // ------------------------------------------------------------------

    // Implementation of business methods defined in remote interface OrderPlacement
    /**
     * Convenience method to place an order using all Strings for the IDs.  
     * Converts district id String to an int and calls the appropriate placeOrder method.
     * @param wID			String Warehouse ID
     * @param dID			String District ID
     * @param cID			Integer Customer ID
     * @param orderLines	    Vector of OrderDetail objects.  
     * Each OrderDetail object represents one line item on the order.  
     * @exception             javax.ejb.RemoteException
     */
    public float placeOrder(String wID, String dID, Integer cID, Vector orderLines)
	throws RemoteException{

	try {
	    int districtInt = Integer.parseInt(dID);
	    return placeOrder(wID, districtInt, cID, orderLines);
	} catch (NumberFormatException nfe) {
	    throw new RemoteException("Unable to covert district id (" + cID + ") to an int.");
	}
			
    }


   /**
     * Place an order.
     * @param wID	       String Warehouse ID
     * @param dID	       int District ID
     * @param cID	       Integer Customer ID
     * @param orderLines       Vector of OrderDetail objects.  
     *                         Each OrderDetail object represents one line item on the order. 
     * @return                 The order number assigned to this order.
     * @exception              javax.ejb.RemoteException
     */
    public float placeOrder(String wID, int dID, Integer cID, Vector orderLines) 
        throws RemoteException {
        float oID = 0;
        logger.log(BasicLevel.DEBUG, "");
        try {	
            // The InitialContext will let us retrieve references to the entity beans we need.
            InitialContext initCtx = new InitialContext();
			
            //Get the Order Number from the District entity bean.
            DistrictHome dHome = (DistrictHome) PortableRemoteObject.narrow(initCtx.lookup("DistrictHome"), DistrictHome.class);
            DistrictID districtID = new DistrictID(dID, wID);
            District district = (District)dHome.findByPrimaryKey(districtID);
            //'true' tells the District to increment the order id.
            oID = district.getNextOrderId(true);       	
            logger.log(BasicLevel.DEBUG,"(District)dHome.findByPrimaryKey("+districtID+");  OK");

            //Update the Stock level for each item in an order line using the Stock entity bean
            StockHome sHome = (StockHome) PortableRemoteObject.narrow(initCtx.lookup("StockHome"), StockHome.class);
            Enumeration lines = orderLines.elements();
            float orderTotal = 0;			
            while(lines.hasMoreElements()){
                OrderDetail od = (OrderDetail)lines.nextElement();
                Integer itemID = od.getItemID();
                int itemQty = od.getItemQty();
                //Calculate the order total while we are going through the orders. 
                orderTotal  += od.getItemAmount();		
                StockID stockID = new StockID(wID, itemID);
                Stock stock = (Stock)sHome.findByPrimaryKey(stockID);
                logger.log(BasicLevel.DEBUG,"(Stock)sHome.findByPrimaryKey("+stockID+");OK  ");
                stock.decreaseStockQuantity(itemQty); 
                logger.log(BasicLevel.DEBUG,"stock.decreaseStockQuantity("+itemQty+")");
            }
			
            //Save the Order to the database by creating an Order entity bean
            OrderHome oHome = (OrderHome) PortableRemoteObject.narrow(initCtx.lookup("OrderHome"), OrderHome.class);
            Order o = oHome.create(wID, dID, cID, oID, orderLines);
            System.out.println(">>>>>>>> CID= "+o.getCustomerID()+ " LC= "+o.getOrderLineCount());
            logger.log(BasicLevel.DEBUG,"OrderHome.create("+wID+","+ dID+","+ cID+","+ oID+","+ orderLines+");  OK");
            //Update the Customer records using the Customer entity bean
            CustomerHome cHome = (CustomerHome) PortableRemoteObject.narrow(initCtx.lookup("CustomerHome"), CustomerHome.class);
           
            Customer customer = (Customer)cHome.findByPrimaryKey(cID);
            customer.updateBalance(orderTotal);
            logger.log(BasicLevel.DEBUG,"(Customer)cHome.findByPrimaryKey("+cID+");  OK");			
            //Write the order to the data queue.
            try{
                writeDataQueue(wID, dID, cID, oID);
            } catch(Exception e){
                System.out.println("WriteDataQueue error: " + e.getMessage());
                throw new RemoteException(e.getMessage());
            }
			
        } catch (Exception e) {
            throw new RemoteException(e.getMessage());
        }
	    logger.log(BasicLevel.DEBUG,"OrderPacementBean: placeOrder return "+oID);
        return oID;
    }

    private void writeDataQueue(String wID, int dID, Integer cID, float oID) throws Exception {}
}

