/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, JBoss Inc., and others contributors as indicated
 * by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * (C) 2005-2006, JBoss Inc.
 */
package org.jboss.bpel.samples.ordermanagement;

import org.apache.log4j.Logger;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import java.rmi.RemoteException;
import java.util.*;
import java.io.Serializable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Order Management Service bean.
 *
 * @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
 */
@Stateless
@Remote(OrderManager.class)
public class OrderManagerBean implements OrderManager, Serializable {

    private Logger logger = Logger.getLogger(OrderManagerBean.class);
    private static Map<String, CustomerOrder> orders = new LinkedHashMap<String, CustomerOrder>();
    private Properties properties;
    private File approvalDir;
    private static final String ORDER_MANAGER_PROPERTIES = "order-manager.properties";
    private static final String ORDER_APPROVAL_DROP_LOCATION = "order.approval.drop.location";

    public OrderManagerBean() throws Exception {
        properties = new Properties();
        try {
            properties.load(getClass().getResourceAsStream("/" + ORDER_MANAGER_PROPERTIES));
        } catch (Exception e) {
            String message = "Failed to load OrderManager properties from root of classpath (/" + ORDER_MANAGER_PROPERTIES + ").";
            logger.error(message, e);
            throw new Exception(message, e);
        }

        String approvalDirName = properties.getProperty(ORDER_APPROVAL_DROP_LOCATION);
        if(approvalDirName == null) {
            throw new Exception("Property '" + ORDER_APPROVAL_DROP_LOCATION + "' not set in '" + ORDER_MANAGER_PROPERTIES + "'.  Configure this property, rebuild and redeploy quickstart.  File located in 'services' folder of the 'webservice_bpel' quickstart.");
        }
        approvalDir = new File(approvalDirName);
        if(!approvalDir.exists() || !approvalDir.isDirectory()) {
            throw new Exception("Directory name set on property '" + ORDER_APPROVAL_DROP_LOCATION + "' in '" + ORDER_MANAGER_PROPERTIES + "' is not available on the system, or is not a directory.  Configure this property, rebuild and redeploy quickstart.  File located in 'services' folder of the 'webservice_bpel' quickstart.");
        }
        if(!approvalDir.canWrite()) {
            throw new Exception("Directory name set on property '" + ORDER_APPROVAL_DROP_LOCATION + "' in '" + ORDER_MANAGER_PROPERTIES + "' is not writable.  Configure this property, rebuild and redeploy quickstart.  File located in 'services' folder of the 'webservice_bpel' quickstart.");
        }
    }
    
    public String createSalesOrder(CustomerOrder customerOrder) throws SalesOrderFault, RemoteException {
        String ordernum = UUID.randomUUID().toString();

        orders.put(ordernum, customerOrder);
        logger.info("Orders: " + orders.keySet());

        System.out.println(customerOrder.getHeader());
        System.out.println(customerOrder.getHeader().getOrderDate());

        return ordernum;
    }

    public boolean cancelOrder(CancelOrder cancelOrder) throws RemoteException {
        return true;
    }

    public Map<String, CustomerOrder> getOrders() throws RemoteException {
        return orders;
    }

    public boolean approveOrder(String orderNumber) throws RemoteException {
        CustomerOrder order = orders.get(orderNumber);

        if(order == null) {
            logger.error("No such order: " + orderNumber);
            return false;
        }

        File orderCSVDrop = new File(approvalDir, orderNumber + ".in.csv");
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(orderCSVDrop);
        } catch (IOException e) {
            logger.error("Failed to create a FileWriter for order file '" + orderCSVDrop.getAbsolutePath() + "'.", e);
            return false;
        }

        try {
            fileWriter.write(orderNumber + "," + order.getHeader().customerNumber + "," + order.getHeader().getBillTo().company + "," + order.getHeader().getOrderDate().getTime());
            orders.remove(orderNumber);
        } catch (IOException e) {
            logger.error("Failed to write order to file '" + orderCSVDrop.getAbsolutePath() + "'.", e);
            return false;
        } finally {
            try {
                fileWriter.flush();
            } catch (IOException e) {
                logger.warn("Failed to flush order to file '" + orderCSVDrop.getAbsolutePath() + "'.", e);
            }
            try {
                fileWriter.close();
            } catch (IOException e) {
                logger.warn("Failed to close order file '" + orderCSVDrop.getAbsolutePath() + "'.", e);
            }
        }

        return true;
    }
}
