/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/

package org.apache.ofbiz.manufacturing.mrp;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.manufacturing.bom.BOMNode;
import org.apache.ofbiz.manufacturing.bom.BOMTree;
import org.apache.ofbiz.manufacturing.jobshopmgt.ProductionRun;
import org.apache.ofbiz.manufacturing.techdata.TechDataServices;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;

/**
 * Proposed Order Object generated by the MRP process or other re-Order process
 *
 */
public class ProposedOrder {

    public static final String module = ProposedOrder.class.getName();
    public static final String resource = "ManufacturingUiLabels";

    protected GenericValue product;
    protected boolean isBuilt;
    protected String productId;
    protected String facilityId;
    protected String manufacturingFacilityId;
    protected String mrpName;
    protected Timestamp requiredByDate;
    protected Timestamp requirementStartDate;
    protected BigDecimal quantity;


    public ProposedOrder(GenericValue product, String facilityId, String manufacturingFacilityId, boolean isBuilt, Timestamp requiredByDate, BigDecimal quantity) {
        this.product = product;
        this.productId = product.getString("productId");
        this.facilityId = facilityId;
        this.manufacturingFacilityId = manufacturingFacilityId;
        this.isBuilt = isBuilt;
        this.requiredByDate = requiredByDate;
        this.quantity = quantity;
        this.requirementStartDate = null;
    }
    /**
     * get the quantity property.
     * @return the quantity property
     **/
    public BigDecimal getQuantity() {
        return quantity;
    }
    /**
     * get the requirementStartDate property.
     * @return the quantity property
     **/
    public Timestamp getRequirementStartDate() {
        return requirementStartDate;
    }
    /**
     * calculate the ProposedOrder requirementStartDate and update the requirementStartDate property.
     * <li>For the build product, <ul>
     *         <li>read the routing associated to the product,
     *         <li>read the routingTask associated to the routing
     *         <li> step by step calculate from the endDate the startDate</ul>
     * <li>For the bought product, the first ProductFacility.daysToShip is used to calculated the startDate
     * @return <ul>
     * <li>if ProposedOrder.isBuild a Map with all the routingTaskId as keys and estimatedStartDate as value.
     * <li>else null.
     **/
    public Map<String, Object> calculateStartDate(int daysToShip, GenericValue routing, Delegator delegator, LocalDispatcher dispatcher, GenericValue userLogin) {
        Map<String, Object> result = null;
        Timestamp endDate = (Timestamp)requiredByDate.clone();
        Timestamp startDate = endDate;
        long timeToShip = daysToShip * 8 * 60 * 60 * 1000;
        if (isBuilt) {
            List<GenericValue> listRoutingTaskAssoc = null;
            if (routing == null) {
                try {
                    Map<String, Object> routingInMap = UtilMisc.<String, Object>toMap("productId", product.getString("productId"), 
                            "ignoreDefaultRouting", "Y", "userLogin", userLogin);
                    Map<String, Object> routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
                    routing = (GenericValue)routingOutMap.get("routing");
                    listRoutingTaskAssoc = UtilGenerics.checkList(routingOutMap.get("tasks"));
                    if (routing == null) {
                        // try to find a routing linked to the virtual product
                        BOMTree tree = null;
                        List<BOMNode> components = new LinkedList<BOMNode>();
                        try {
                            tree = new BOMTree(product.getString("productId"), "MANUF_COMPONENT", requiredByDate, BOMTree.EXPLOSION_SINGLE_LEVEL, delegator, dispatcher, userLogin);
                            tree.setRootQuantity(quantity);
                            tree.print(components, true);
                            if (components.size() > 0) components.remove(0);
                        } catch (Exception exc) {
                            Debug.logWarning(exc.getMessage(), module);
                            tree = null;
                        }
                        if (tree != null && tree.getRoot() != null && tree.getRoot().getProduct() != null) {
                            routingInMap = UtilMisc.toMap("productId", tree.getRoot().getProduct().getString("productId"), "userLogin", userLogin);
                            routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
                            routing = (GenericValue)routingOutMap.get("routing");
                        }
                    }
                } catch (GenericServiceException gse) {
                    Debug.logWarning(gse.getMessage(), module);
                }
            }
            if (routing != null) {
                result = new HashMap<String, Object>();
                //Looks for all the routingTask (ordered by inversed (begin from the end) sequence number)
                if (listRoutingTaskAssoc == null) {
                    try {
                        Map<String, Object> routingTasksInMap = UtilMisc.<String, Object>toMap("workEffortId", routing.getString("workEffortId"),
                                "userLogin", userLogin);
                        Map<String, Object> routingTasksOutMap = dispatcher.runSync("getRoutingTaskAssocs", routingTasksInMap);
                        listRoutingTaskAssoc = UtilGenerics.checkList(routingTasksOutMap.get("routingTaskAssocs"));
                    } catch (GenericServiceException gse) {
                        Debug.logWarning(gse.getMessage(), module);
                    }
                }
            }
            if (listRoutingTaskAssoc != null) {
                for (int i = 1; i <= listRoutingTaskAssoc.size(); i++) {
                    GenericValue routingTaskAssoc = listRoutingTaskAssoc.get(listRoutingTaskAssoc.size() - i);
                    if (EntityUtil.isValueActive(routingTaskAssoc, endDate)) {
                        GenericValue routingTask = null;
                        try {
                            routingTask = routingTaskAssoc.getRelatedOne("ToWorkEffort", true);
                        } catch (GenericEntityException e) {
                            Debug.logError(e.getMessage(),  module);
                        }
                        // Calculate the estimatedStartDate
                        long totalTime = ProductionRun.getEstimatedTaskTime(routingTask, quantity, dispatcher);
                        if (i == listRoutingTaskAssoc.size()) {
                            // add the daysToShip at the end of the routing
                            totalTime += timeToShip;
                        }
                        startDate = TechDataServices.addBackward(TechDataServices.getTechDataCalendar(routingTask),endDate, totalTime);
                        // record the routingTask with the startDate associated
                        result.put(routingTask.getString("workEffortId"),startDate);
                        endDate = startDate;
                    }
                }
            } else {
                // routing is null
                Debug.logError("No routing found for product = "+ product.getString("productId"), module);
            }
        } else {
            // the product is purchased
            // TODO: REVIEW this code
            try {
                GenericValue techDataCalendar = product.getDelegator().findOne("TechDataCalendar", UtilMisc.toMap("calendarId", "SUPPLIER"), true);
                startDate = TechDataServices.addBackward(techDataCalendar, endDate, timeToShip);
            } catch (GenericEntityException e) {
                Debug.logError(e, "Error : reading SUPPLIER TechDataCalendar: " + e.getMessage(), module);
            }
        }
        requirementStartDate = startDate;
        return result;
    }


    /**
     * calculate the ProposedOrder quantity and update the quantity property.
     * Read the first ProductFacility.reorderQuantity and calculate the quantity : if (quantity < reorderQuantity) quantity = reorderQuantity;
     **/
    // FIXME: facilityId
    public void calculateQuantityToSupply(BigDecimal reorderQuantity, BigDecimal minimumStock, ListIterator<GenericValue>  listIterIEP) {
        //      TODO : use a better algorithm using Order management cost et Product Stock cost to calculate the re-order quantity
        //                     the variable listIterIEP will be used for that
        if (quantity.compareTo(reorderQuantity) < 0) {
            quantity = reorderQuantity;
        }
    }

    /**
     * create a ProposedOrder in the Requirement Entity calling the createRequirement service.
     * @param ctx The DispatchContext used to call service to create the Requirement Entity record.
     * @return String the requirementId
     **/
    public String create(DispatchContext ctx, GenericValue userLogin) {
        if ("WIP".equals(product.getString("productTypeId"))) {
            // No requirements for Work In Process products
            return null;
        }
        LocalDispatcher dispatcher = ctx.getDispatcher();
        Delegator delegator = ctx.getDelegator();
        Map<String, Object> parameters = UtilMisc.<String, Object>toMap("userLogin", userLogin);
        if (isBuilt) {
            try {
                List<BOMNode> bom = new LinkedList<BOMNode>();
                BOMTree tree = new BOMTree(productId, "MANUF_COMPONENT", null, BOMTree.EXPLOSION_MANUFACTURING, delegator, dispatcher, userLogin);
                tree.setRootQuantity(quantity);
                tree.print(bom);
                requirementStartDate = tree.getRoot().getStartDate(manufacturingFacilityId, requiredByDate, true);
            } catch (Exception e) {
                Debug.logError(e,"Error : computing the requirement start date. " + e.getMessage(), module);
            }
        }
        parameters.put("productId", productId);
        parameters.put("statusId", "REQ_PROPOSED");
        parameters.put("facilityId", (isBuilt? manufacturingFacilityId: facilityId));
        parameters.put("requiredByDate", requiredByDate);
        parameters.put("requirementStartDate", requirementStartDate);
        parameters.put("quantity", quantity);
        parameters.put("requirementTypeId", (isBuilt? "INTERNAL_REQUIREMENT" : "PRODUCT_REQUIREMENT"));
        if (mrpName != null) {
            parameters.put("description", "MRP_" + mrpName);
        } else {
            parameters.put("description", "Automatically generated by MRP");
        }
        try {
            Map<String, Object> result = dispatcher.runSync("createRequirement", parameters);
            return (String) result.get("requirementId");
        } catch (GenericServiceException e) {
            Debug.logError(e,"Error : createRequirement with parameters = "+parameters+"--"+e.getMessage(), module);
            return null;
        }
    }

    public void setMrpName(String mrpName) {
        this.mrpName = mrpName;
    }
}
