/*
 * Copyright (c) 2004, 2005, ADAPT project partners (IST-2001-37126).
 *
 * PurchaseOrderBasicServiceBean.java
 */

package org.eu.adapt.demonstrator.bs.retailer;

import java.util.Collection;
import java.util.Iterator;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
import javax.ejb.SessionContext;
import javax.ejb.SessionBean;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eu.adapt.demonstrator.eb.retailer.CustomerReferenceHomeLocal;
import org.eu.adapt.demonstrator.eb.retailer.CustomerReferenceLocal;
import org.eu.adapt.demonstrator.eb.retailer.InventoryLocal;
import org.eu.adapt.demonstrator.eb.retailer.ProductHomeLocal;
import org.eu.adapt.demonstrator.eb.retailer.ProductLocal;
import org.eu.adapt.demonstrator.eb.retailer.PurchaseOrderHomeLocal;
import org.eu.adapt.demonstrator.eb.retailer.PurchaseOrderItemHomeLocal;
import org.eu.adapt.demonstrator.eb.retailer.PurchaseOrderItemLocal;
import org.eu.adapt.demonstrator.eb.retailer.PurchaseOrderLocal;
import org.eu.adapt.demonstrator.web.demo.RetailerItemsDefs;
import org.eu.adapt.services.demo_1_1.retailer.PurchaseOrderBasicService_wsdl.types.PurchaseOrderState;
import org.eu.adapt.services.demo_1_1.retailer.PurchaseOrderBasicService_wsdl.PurchaseOrderBasicServicePortType;
import org.ws_i.www.SampleApplications.SupplyChainManagement._2002_08.RetailOrder_xsd.PartsOrderItem;
import org.ws_i.www.SampleApplications.SupplyChainManagement._2002_08.RetailOrder_xsd.PartsOrderResponseItem;
import org.ws_i.www.SampleApplications.SupplyChainManagement._2002_08.RetailOrder_xsd.PartsOrderResponseType;
import org.ws_i.www.SampleApplications.SupplyChainManagement._2002_08.RetailOrder_xsd.PartsOrderType;

public class PurchaseOrderBasicServiceBean implements SessionBean, PurchaseOrderBasicServicePortType
{
    public String[] listPurchaseOrders()
       throws RemoteException
    {
        String[] purchaseOrderNames = null;

        try
        {
            Collection purchaseOrders         = _purchaseOrderHome.findAll();
            Iterator   purchaseOrdersIterator = purchaseOrders.iterator();

            purchaseOrderNames = new String[purchaseOrders.size()];
            int index = 0;
            while (purchaseOrdersIterator.hasNext())
            {
                purchaseOrderNames[index] = ((PurchaseOrderLocal) purchaseOrdersIterator.next()).getNumber();
                index++;
            }
        }
        catch (FinderException findException)
        {
            purchaseOrderNames = new String[0];
            System.out.println("Unable to find all purchaseOrders: \"" + findException + "\"");
        }
        catch (Exception exception)
        {
            purchaseOrderNames = new String[0];
            System.out.println("Exception: \"" + exception + "\"");
        }
        catch (Error error)
        {
            purchaseOrderNames = new String[0];
            System.out.println("Error: \"" + error + "\"");
        }

        return purchaseOrderNames;
    }

    public PurchaseOrderState getPurchaseOrderState(String purchaseOrderName)
        throws RemoteException
    {
        PurchaseOrderState state = new PurchaseOrderState();

        try
        {
            PurchaseOrderLocal purchaseOrder = _purchaseOrderHome.findByPrimaryKey(purchaseOrderName);

            state.setNumber(purchaseOrder.getNumber());

            int index = 0;

            CustomerReferenceLocal customerReference = purchaseOrder.getCustomerReference();
            if (customerReference != null)
                state.setCustomerReferenceName(customerReference.getName());
            else
                state.setCustomerReferenceName(null);

            Collection purchaseOrderItems         = purchaseOrder.getPurchaseOrderItems();
            Iterator   purchaseOrderItemsIterator = purchaseOrderItems.iterator();
            String[]   purchaseOrderItemNumbers   = new String[purchaseOrderItems.size()];
            index = 0;
            while (purchaseOrderItemsIterator.hasNext())
            {
                purchaseOrderItemNumbers[index] = ((PurchaseOrderItemLocal) purchaseOrderItemsIterator.next()).getNumber();
                index++;
            }
            state.setPurchaseOrderItemNumbers(purchaseOrderItemNumbers);
       }
        catch (FinderException finderException)
        {
            System.out.println("Unable to find purchaseOrder: \"" + purchaseOrderName + "\"");
        }
        catch (Exception exception)
        {
            System.out.println("PurchaseOrderBasicServiceBean.getPurchaseOrderState exception: \"" + exception + "\"");
            throw new RemoteException("PurchaseOrderBasicServiceBean.getPurchaseOrderState exception", exception);
        }
        catch (Error error)
        {
            System.out.println("PurchaseOrderBasicServiceBean.getPurchaseOrderState error: \"" + error + "\"");
            throw new RemoteException("PurchaseOrderBasicServiceBean.getPurchaseOrderState error", error);
        }

        return state;
    }

    public boolean checkPurchaseOrder(PartsOrderType partsOrder)
        throws RemoteException
    {
        boolean partsOrderIsValid = true;

        PartsOrderItem[] partsOrderItems = partsOrder.getItem();
        for (int index = 0; partsOrderIsValid && (index < partsOrderItems.length); index++)
        {
            String productNumber = partsOrderItems[index].getProductNumber();
            try
            {
                ProductLocal product             = _productHome.findByPrimaryKey(productNumber);
                Collection   inventories         = product.getInventories();
                Iterator     inventoriesIterator = inventories.iterator();
                while (partsOrderIsValid && inventoriesIterator.hasNext())
                {
                    InventoryLocal inventory = (InventoryLocal) inventoriesIterator.next();

                    partsOrderIsValid = inventory.getAmount() > partsOrderItems[index].getQuantity();
                }
            }
            catch (FinderException finderException)
            {
                System.out.println("Unable to find product: \"" + productNumber + "\"");
                partsOrderIsValid = false;
            }
        }

        return partsOrderIsValid;
    }

    public PartsOrderResponseType addPurchaseOrder(PartsOrderType partsOrder)
        throws RemoteException
    {
        PartsOrderResponseType partsOrderResponse = new PartsOrderResponseType();

        PartsOrderItem[]         partsOrderItems         = partsOrder.getItem();
        PartsOrderResponseItem[] partsOrderResponseItems = new PartsOrderResponseItem[partsOrderItems.length];
        try
        {
            CustomerReferenceLocal customerReference = _customerReferenceHome.findByPrimaryKey(RetailerItemsDefs.CUSTOMERREFERENCE_0);
            PurchaseOrderLocal     purchaseOrder     = _purchaseOrderHome.create(customerReference);

            for (int partsOrderItemIndex = 0; partsOrderItemIndex < partsOrderItems.length; partsOrderItemIndex++)
            {
                String name     = partsOrderItems[partsOrderItemIndex].getProductNumber();
                int    quantity = partsOrderItems[partsOrderItemIndex].getQuantity();
                float  price    = partsOrderItems[partsOrderItemIndex].getPrice();

                ProductLocal product = _productHome.findByPrimaryKey(name);

                PurchaseOrderItemLocal purchaseOrderItem = _purchaseOrderItemHome.create(purchaseOrder, product, quantity, price);

                purchaseOrder.getPurchaseOrderItems().add(purchaseOrderItem);
                
                partsOrderResponseItems[partsOrderItemIndex] = new PartsOrderResponseItem();
                partsOrderResponseItems[partsOrderItemIndex].setProductNumber(name);
                partsOrderResponseItems[partsOrderItemIndex].setQuantity(quantity);
                partsOrderResponseItems[partsOrderItemIndex].setPrice(price);
            }
            
            partsOrderResponse.setItem(partsOrderResponseItems);
        }
        catch (Exception exception)
        {
            System.out.println("PurchaseOrderBasicServiceBean.addPurchaseOrder Exception: \"" + exception + "\"");
            _sessionContext.setRollbackOnly();
        }
        catch (Error error)
        {
            System.out.println("PurchaseOrderBasicServiceBean.addPurchaseOrder Error: \"" + error + "\"");
            _sessionContext.setRollbackOnly();
        }

        return partsOrderResponse;
    }
    
    public PartsOrderResponseType createEmptyPartsOrderResponse()
        throws RemoteException
    {
        PartsOrderResponseType   partsOrderResponse      = new PartsOrderResponseType();
        PartsOrderResponseItem[] partsOrderResponseItems = new PartsOrderResponseItem[0];
        
        partsOrderResponse.setItem(partsOrderResponseItems);

        return partsOrderResponse;        
    }

    public void setSessionContext(SessionContext sessionContext)
    {
        _sessionContext = sessionContext;
    }

    public void unsetSessionContext()
    {
        _sessionContext = null;
    }

    public void ejbCreate()
    {
        try
        {
            InitialContext initialContext = new InitialContext();

//            _purchaseOrderHome     = (PurchaseOrderHomeLocal) initialContext.lookup("java:comp/env/ejb/PurchaseOrderHomeLocal");
//            _purchaseItemOrderHome = (PurchaseOrderItemHomeLocal) initialContext.lookup("java:comp/env/ejb/PurchaseOrderItemHomeLocal");
//            _customerReferenceHome = (CustomerReferenceHomeLocal) initialContext.lookup("java:comp/env/ejb/CustomerReferenceHomeLocal");
//            _productHome           = (ProductHomeLocal) initialContext.lookup("java:comp/env/ejb/ProductHomeLocal");
            _purchaseOrderHome     = (PurchaseOrderHomeLocal) initialContext.lookup("local/Retailer_PurchaseOrderEB");
            _purchaseOrderItemHome = (PurchaseOrderItemHomeLocal) initialContext.lookup("local/Retailer_PurchaseOrderItemEB");
            _customerReferenceHome = (CustomerReferenceHomeLocal) initialContext.lookup("local/Retailer_CustomerReferenceEB");
            _productHome           = (ProductHomeLocal) initialContext.lookup("local/Retailer_ProductEB");

            initialContext.close();
        }
        catch (NamingException namingException)
        {
            System.out.println("Name lookup problem: \"" + namingException + "\"");
            namingException.printStackTrace(System.out);
        }
        catch (Exception exception)
        {
            System.out.println("Problem: \"" + exception + "\"");
            exception.printStackTrace(System.out);
        }
        catch (Error error)
        {
            System.out.println("Problem: \"" + error + "\"");
            error.printStackTrace(System.out);
        }
    }

    public void ejbActivate()
    {
    }

    public void ejbPassivate()
    {
    }

    public void ejbLoad()
    {
    }

    public void ejbStore()
    {
    }    

    public void ejbRemove()
    {
        _purchaseOrderHome     = null;
        _purchaseOrderItemHome = null;
        _customerReferenceHome = null;
        _productHome           = null;
    }

    private SessionContext _sessionContext = null;
    
    private transient PurchaseOrderHomeLocal     _purchaseOrderHome     = null;
    private transient PurchaseOrderItemHomeLocal _purchaseOrderItemHome = null;
    private transient CustomerReferenceHomeLocal _customerReferenceHome = null;
    private transient ProductHomeLocal           _productHome           = null;
}