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

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

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.manufacturer.FinishedGoodsLocal;
import org.eu.adapt.demonstrator.eb.manufacturer.InventoryItemLocal;
import org.eu.adapt.demonstrator.eb.manufacturer.ProductionLineHomeLocal;
import org.eu.adapt.demonstrator.eb.manufacturer.ProductionLineLocal;
import org.eu.adapt.demonstrator.eb.manufacturer.StorehouseLocal;
import org.eu.adapt.services.demo_1_1.manufacturer.ProductionLineBasicService_wsdl.types.ProductionLineState;
import org.eu.adapt.services.demo_1_1.manufacturer.ProductionLineBasicService_wsdl.ProductionLineBasicServicePortType;

public class ProductionLineBasicServiceBean implements SessionBean, ProductionLineBasicServicePortType
{
    public String[] listProductionLines()
       throws RemoteException
    {
        String[] productionLineNames = null;
        
        try
        {
            Collection productionLines       = _productionLineHome.findAll();
            Iterator productionLinesIterator = productionLines.iterator();

            productionLineNames = new String[productionLines.size()];
            int index = 0;
            while (productionLinesIterator.hasNext())
            {
                productionLineNames[index] = ((ProductionLineLocal) productionLinesIterator.next()).getName();
                index++;
            }
        }
        catch (FinderException findException)
        {
            productionLineNames = new String[0];
            System.err.println("Unable to find all production lines: \"" + findException + "\"");
        }
        catch (Exception exception)
        {
            productionLineNames = new String[0];
            System.err.println("Exception: \"" + exception + "\"");
        }
        catch (Error error)
        {
            productionLineNames = new String[0];
            System.err.println("Error: \"" + error + "\"");
        }

        return productionLineNames;
    }

    public ProductionLineState getProductionLineState(String productionLineName)
        throws RemoteException
    {
        ProductionLineState state = new ProductionLineState();
        
        try
        {
            ProductionLineLocal productionLine = _productionLineHome.findByPrimaryKey(productionLineName);
                        
            Collection finishedGoods         = productionLine.getFinishedGoods();
            Iterator   finishedGoodsIterator = finishedGoods.iterator();
            String[]   finishedGoodsNames    = new String[finishedGoods.size()];
            int index = 0;
            while (finishedGoodsIterator.hasNext())
            {
                finishedGoodsNames[index] = ((FinishedGoodsLocal) finishedGoodsIterator.next()).getId();
                index++;
            }
            state.setFinishedGoodsNames(finishedGoodsNames);

            StorehouseLocal storehouse = productionLine.getStorehouse();
            if (storehouse != null)
                state.setStorehouseName(storehouse.getName());
            else
                state.setStorehouseName(null);
        }
        catch (FinderException finderException)
        {
            System.err.println("Unable to find production line: \"" + productionLineName + "\"");
        }
        catch (Exception exception)
        {
            System.err.println("ProductionLineBasicServiceBean.getProductionLineState exception: \"" + exception + "\"");
            throw new RemoteException("ProductionLineBasicServiceBean.getProductionLineState exception", exception);
        }
        catch (Error error)
        {
            System.err.println("ProductionLineBasicServiceBean.getProductionLineState error: \"" + error + "\"");
            throw new RemoteException("ProductionLineBasicServiceBean.getProductionLineState error", error);
        }

        return state;
    }

    public boolean restock(String productionLineName, String finishedGoodsID, int amount)
        throws RemoteException
    {
        boolean done = false;

        try
        {
            ProductionLineLocal productionLine = _productionLineHome.findByPrimaryKey(productionLineName);
            StorehouseLocal     storehouse     = productionLine.getStorehouse();

            Collection         inventoryItems         = storehouse.getInventoryItems();
            Iterator           inventoryItemsIterator = inventoryItems.iterator();
            InventoryItemLocal inventoryItem          = null;
            while ((inventoryItem == null) && inventoryItemsIterator.hasNext())
            {
                inventoryItem                 = (InventoryItemLocal) inventoryItemsIterator.next();
                String presentFinishedGoodsID = inventoryItem.getFinishedGoods().getId();
                
                if (! finishedGoodsID.equals(presentFinishedGoodsID))
                    inventoryItem = null;
            }
            
            if ((inventoryItem.getAmountFree() + inventoryItem.getAmountAllocated() + amount) <= inventoryItem.getMaxAmount())
            {
                inventoryItem.setAmountFree(inventoryItem.getAmountFree() + amount);
                done = true;
            }
            else
                _sessionContext.setRollbackOnly();
        }
        catch (Exception exception)
        {
            System.err.println("ProductionLineBasicServiceBean.updateRestock exception: \"" + exception + "\"");
            exception.printStackTrace(System.err);
            done = false;
            _sessionContext.setRollbackOnly();
            throw new RemoteException("ProductionLineBasicServiceBean.updateRestock exception", exception);
        }
        catch (Error error)
        {
            System.err.println("ProductionLineBasicServiceBean.updateRestock error: \"" + error + "\"");
            error.printStackTrace(System.err);
            done = false;
            _sessionContext.setRollbackOnly();
            throw new RemoteException("ProductionLineBasicServiceBean.updateRestock error", error);
        }
        
        return done;
    }

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

    public void unsetSessionContext()
    {
        _sessionContext = null;
    }

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

//            _productionLineHome = (ProductionLineHomeLocal) initialContext.lookup("java:comp/env/ejb/ProductionLineHomeLocal");
            _productionLineHome = (ProductionLineHomeLocal) initialContext.lookup("local/Manufacturer_ProductionLineEB");

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

    public void ejbActivate()
    {
    }

    public void ejbPassivate()
    {
    }

    public void ejbLoad()
    {
    }

    public void ejbStore()
    {
    }    

    public void ejbRemove()
    {
        _productionLineHome = null;
    }

    private SessionContext _sessionContext = null;
    
    private transient ProductionLineHomeLocal _productionLineHome = null;
}