/*
 * 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.service.engine;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.finder.PrimaryKeyFinder;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelField;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.ModelParam;
import org.apache.ofbiz.service.ModelService;
import org.apache.ofbiz.service.ServiceDispatcher;
import org.apache.ofbiz.service.ServiceUtil;

/**
 * Standard Java Static Method Service Engine
 */
public final class EntityAutoEngine extends GenericAsyncEngine {

    public static final String module = EntityAutoEngine.class.getName();
    public static final String resource = "ServiceErrorUiLabels";
    private static final List<String> availableInvokeActionNames = UtilMisc.toList("create", "update", "delete", "expire");

    public EntityAutoEngine(ServiceDispatcher dispatcher) {
        super(dispatcher);
    }

    /**
     * @see org.apache.ofbiz.service.engine.GenericEngine#runSyncIgnore(java.lang.String, org.apache.ofbiz.service.ModelService, java.util.Map)
     */
    @Override
    public void runSyncIgnore(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
        runSync(localName, modelService, context);
    }

    /**
     * @see org.apache.ofbiz.service.engine.GenericEngine#runSync(java.lang.String, org.apache.ofbiz.service.ModelService, java.util.Map)
     */
    @Override
    public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> parameters) throws GenericServiceException {
        // static java service methods should be: public Map<String, Object> methodName(DispatchContext dctx, Map<String, Object> context)
        DispatchContext dctx = dispatcher.getLocalContext(localName);
        Locale locale = (Locale) parameters.get("locale");
        Map<String, Object> result = ServiceUtil.returnSuccess();

        // check the package and method names
        if (modelService.invoke == null || !availableInvokeActionNames.contains(modelService.invoke)) {
            throw new GenericServiceException("In Service [" + modelService.name + "] the invoke value must be create, update, or delete for entity-auto engine");
        }

        if (UtilValidate.isEmpty(modelService.defaultEntityName)) {
            throw new GenericServiceException("In Service [" + modelService.name + "] you must specify a default-entity-name for entity-auto engine");
        }

        ModelEntity modelEntity = dctx.getDelegator().getModelEntity(modelService.defaultEntityName);
        if (modelEntity == null) {
            throw new GenericServiceException("In Service [" + modelService.name + "] the specified default-entity-name [" + modelService.defaultEntityName + "] is not valid");
        }

        try {
            boolean allPksInOnly = true;
            List<String> pkFieldNameOutOnly = null;
            /* Check for each pk if it's :
             * 1. part IN 
             * 2. or part IN and OUT, but without value but present on parameters map
             * Help the engine to determinate the operation to realize for a create call or validate that
             * any pk is present for update/delete call.
             */
            for (ModelField pkField: modelEntity.getPkFieldsUnmodifiable()) {
                ModelParam pkParam = modelService.getParam(pkField.getName());
                boolean pkValueInParameters = pkParam.isIn() && UtilValidate.isNotEmpty(parameters.get(pkParam.getFieldName()));
                if (pkParam.isOut() && !pkValueInParameters) {
                    if (pkFieldNameOutOnly == null) {
                        pkFieldNameOutOnly = new LinkedList<String>();
                        allPksInOnly = false;
                    }
                    pkFieldNameOutOnly.add(pkField.getName());
                }
            }

            switch (modelService.invoke) {
            case "create":
                result = invokeCreate(dctx, parameters, modelService, modelEntity, allPksInOnly, pkFieldNameOutOnly);
                result.put("successMessage", UtilProperties.getMessage("ServiceUiLabels", "EntityCreatedSuccessfully", UtilMisc.toMap("entityName", modelEntity.getEntityName()), locale));
                break;
            case "update":
                result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
                result.put("successMessage", UtilProperties.getMessage("ServiceUiLabels", "EntityUpdatedSuccessfully", UtilMisc.toMap("entityName", modelEntity.getEntityName()), locale));
                break;
            case "delete":
                result = invokeDelete(dctx, parameters, modelService, modelEntity, allPksInOnly);
                result.put("successMessage", UtilProperties.getMessage("ServiceUiLabels", "EntityDeletedSuccessfully", UtilMisc.toMap("entityName", modelEntity.getEntityName()), locale));
                break;
            case "expire":
                result = invokeExpire(dctx, parameters, modelService, modelEntity, allPksInOnly);
                if (ServiceUtil.isSuccess(result)) {
                    result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
                }
                result.put("successMessage", UtilProperties.getMessage("ServiceUiLabels", "EntityExpiredSuccessfully", UtilMisc.toMap("entityName", modelEntity.getEntityName()), locale));
                break;
            default:
                break;
            }
            GenericValue crudValue = (GenericValue) result.get("crudValue");
            if (crudValue != null) {
                result.remove("crudValue");
                result.putAll(modelService.makeValid(crudValue, "OUT"));
            }
        } catch (GeneralException e) {
            Debug.logError(e, "Error doing entity-auto operation for entity [" + modelEntity.getEntityName() + "] in service [" + modelService.name + "]: " + e.toString(), module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceEntityAutoOperation", UtilMisc.toMap("entityName", modelEntity.getEntityName(), "serviceName", modelService.name,"errorString", e.toString()), locale));
        }
        result.put(ModelService.SUCCESS_MESSAGE, result.get("successMessage"));
        return result;
    }

    private static Map<String, Object> invokeCreate(DispatchContext dctx, Map<String, Object> parameters, ModelService modelService, ModelEntity modelEntity, boolean allPksInOnly, List<String> pkFieldNameOutOnly)
            throws GeneralException {
        Locale locale = (Locale) parameters.get("locale");
        Map<String, Object> result = ServiceUtil.returnSuccess();

        GenericValue newEntity = dctx.getDelegator().makeValue(modelEntity.getEntityName());

        boolean isSinglePk = modelEntity.getPksSize() == 1;
        boolean isDoublePk = modelEntity.getPksSize() == 2;
        Iterator<ModelField> pksIter = modelEntity.getPksIterator();

        ModelField singlePkModeField = isSinglePk ? pksIter.next() : null;
        ModelParam singlePkModelParam = isSinglePk ? modelService.getParam(singlePkModeField.getName()) : null;
        boolean isSinglePkIn = isSinglePk ? singlePkModelParam.isIn() : false;
        boolean isSinglePkOut = isSinglePk ? singlePkModelParam.isOut() : false;

        ModelParam doublePkPrimaryInParam = null;
        ModelParam doublePkSecondaryOutParam = null;
        ModelField doublePkSecondaryOutField = null;
        if (isDoublePk) {
            ModelField firstPkField = pksIter.next();
            ModelParam firstPkParam = modelService.getParam(firstPkField.getName());
            ModelField secondPkField = pksIter.next();
            ModelParam secondPkParam = modelService.getParam(secondPkField.getName());
            if (firstPkParam.isIn() && secondPkParam.isOut()) {
                doublePkPrimaryInParam = firstPkParam;
                doublePkSecondaryOutParam = secondPkParam;
                doublePkSecondaryOutField = secondPkField;
            } else if (firstPkParam.isOut() && secondPkParam.isIn()) {
                doublePkPrimaryInParam = secondPkParam;
                doublePkSecondaryOutParam = firstPkParam;
                doublePkSecondaryOutField = firstPkField;
            } else {
                // we don't have an IN and an OUT... so do nothing and leave them null
            }
        }

        if (isSinglePk && isSinglePkOut && !isSinglePkIn) {
            /*
             **** primary sequenced primary key ****
             *
            <auto-attributes include="pk" mode="OUT" optional="false"/>
             *
            <make-value entity-name="Example" value-name="newEntity"/>
            <sequenced-id-to-env sequence-name="Example" env-name="newEntity.exampleId"/> <!-- get the next sequenced ID -->
            <field-to-result field-name="newEntity.exampleId" result-name="exampleId"/>
            <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
            <create-value value-name="newEntity"/>
             *
             */

            String sequencedId = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
            newEntity.set(singlePkModeField.getName(), sequencedId);
        } else if (isSinglePk && isSinglePkOut && isSinglePkIn) {
            /*
             **** primary sequenced key with optional override passed in ****
             *
            <auto-attributes include="pk" mode="INOUT" optional="true"/>
             *
            <make-value value-name="newEntity" entity-name="Product"/>
            <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
            <set from-field="parameters.productId" field="newEntity.productId"/>
            <if-empty field="newEntity.productId">
                <sequenced-id-to-env sequence-name="Product" env-name="newEntity.productId"/>
            <else>
                <check-id field-name="productId" map-name="newEntity"/>
                <check-errors/>
            </else>
            </if-empty>
            <field-to-result field-name="productId" map-name="newEntity" result-name="productId"/>
            <create-value value-name="newEntity"/>
             *
             */

            Object pkValue = parameters.get(singlePkModelParam.name);
            if (UtilValidate.isEmpty(pkValue)) {
                pkValue = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
            } else {
                // pkValue passed in, check and if there are problems return an error

                if (pkValue instanceof String) {
                    StringBuffer errorDetails = new StringBuffer();
                    if (!UtilValidate.isValidDatabaseId((String) pkValue, errorDetails)) {
                        return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceParameterValueNotValid", UtilMisc.toMap("parameterName", singlePkModelParam.name,"errorDetails", errorDetails), locale));
                    }
                }
            }
            newEntity.set(singlePkModeField.getName(), pkValue);
            GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
            if (lookedUpValue != null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueFound", UtilMisc.toMap("pkFields", newEntity.getPkShortValueString()), locale));
            }
        } else if (isDoublePk && doublePkPrimaryInParam != null && doublePkSecondaryOutParam != null) {
            /*
             **** secondary sequenced primary key ****
             *
            <auto-attributes include="pk" mode="IN" optional="false"/>
            <override name="exampleItemSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->
             *
            <make-value entity-name="ExampleItem" value-name="newEntity"/>
            <set-pk-fields map-name="parameters" value-name="newEntity"/>
            <make-next-seq-id value-name="newEntity" seq-field-name="exampleItemSeqId"/> <!-- this finds the next sub-sequence ID -->
            <field-to-result field-name="newEntity.exampleItemSeqId" result-name="exampleItemSeqId"/>
            <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
            <create-value value-name="newEntity"/>
             */

            newEntity.setPKFields(parameters, true);
            dctx.getDelegator().setNextSubSeqId(newEntity, doublePkSecondaryOutField.getName(), 5, 1);
        } else if (allPksInOnly) {
            /*
             **** plain specified primary key ****
             *
            <auto-attributes include="pk" mode="IN" optional="false"/>
             *
            <make-value entity-name="Example" value-name="newEntity"/>
            <set-pk-fields map-name="parameters" value-name="newEntity"/>
            <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
            <create-value value-name="newEntity"/>
             *
             */
            newEntity.setPKFields(parameters, true);
            //with all pks present on parameters, check if the entity is not already exists.
            GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
            if (lookedUpValue != null) {
                return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueFound", UtilMisc.toMap("pkFields", newEntity.getPkShortValueString()), locale));
            }
        } else {
            /* We haven't all Pk and their are 3 or more, now check if isn't a associate entity with own sequence
            <set-pk-fields map="parameters" value-field="newEntity"/>
            <sequenced-id sequence-name="ExempleItemAssoc" field="newEntity.exempleItemAssocId"/>
            <create-value value-field="newEntity"/>
             */
            if (pkFieldNameOutOnly != null && pkFieldNameOutOnly.size() == 1) {
                newEntity.setPKFields(parameters, true);
                String pkFieldName = pkFieldNameOutOnly.get(0);
                //if it's a fromDate, don't update it now, it's will be done next step
                if (! "fromDate".equals(pkFieldName)) { 
                    String pkValue = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
                    newEntity.set(pkFieldName, pkValue);
                }
            } else {
                throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the create invoke option: " +
                        "could not find a valid combination of primary key settings to do a known create operation; options include: " +
                        "1. a single OUT pk for primary auto-sequencing, " +
                        "2. a single INOUT pk for primary auto-sequencing with optional override, " +
                        "3. a 2-part pk with one part IN (existing primary pk) and one part OUT (the secondary pk to sub-sequence), " +
                        "4. a N-part pk with N-1 part IN and one party OUT only (missing pk is a sub-sequence mainly for entity assoc), " +
                        "5. all pk fields are IN for a manually specified primary key");
            }
        }

        // handle the case where there is a fromDate in the pk of the entity, and it is optional or undefined in the service def, populate automatically
        ModelField fromDateField = modelEntity.getField("fromDate");
        if (fromDateField != null && fromDateField.getIsPk()) {
            ModelParam fromDateParam = modelService.getParam("fromDate");
            if (fromDateParam == null || parameters.get("fromDate") == null) {
                newEntity.set("fromDate", UtilDateTime.nowTimestamp());
            }
        }

        newEntity.setNonPKFields(parameters, true);
        if (modelEntity.getField("createdDate") != null) {
            newEntity.set("createdDate", UtilDateTime.nowTimestamp());
            if (modelEntity.getField("createdByUserLogin") != null) {
                GenericValue userLogin = (GenericValue) parameters.get("userLogin");
                if (userLogin != null) {
                    newEntity.set("createdByUserLogin", userLogin.get("userLoginId"));
                    if (modelEntity.getField("lastModifiedByUserLogin") != null) {
                        newEntity.set("lastModifiedByUserLogin", userLogin.get("userLoginId"));
                    } else if (modelEntity.getField("changedByUserLogin") != null) {
                        newEntity.set("changedByUserLogin", userLogin.get("userLoginId"));
                    }
                }
            }
            if (modelEntity.getField("lastModifiedDate") != null) {
                newEntity.set("lastModifiedDate", UtilDateTime.nowTimestamp());
            } else if (modelEntity.getField("changedDate") != null) {
                newEntity.set("changedDate", UtilDateTime.nowTimestamp());
            }
        }

        if (modelEntity.getField("changeByUserLoginId") != null) {
            GenericValue userLogin = (GenericValue) parameters.get("userLogin");
            if (userLogin != null) {
                newEntity.set("changeByUserLoginId", userLogin.get("userLoginId"));
            } else {
                throw new GenericServiceException("You call a creation on entity that require the userLogin to track the activity, please controle that your service definition has auth='true'");
            }

            //Oh changeByUserLoginId detected, check if an EntityStatus concept
            if (modelEntity.getEntityName().endsWith("Status")) {
                if (modelEntity.getField("statusDate") != null && parameters.get("statusDate") == null) {
                    newEntity.set("statusDate", UtilDateTime.nowTimestamp());

                    //if a statusEndDate is present, resolve the last EntityStatus to store this value on the previous element
                    if (modelEntity.getField("statusEndDate") != null) {
                        ModelEntity relatedEntity = dctx.getDelegator().getModelEntity(modelEntity.getEntityName().replaceFirst("Status", ""));
                        if (relatedEntity != null) {
                            Map<String, Object> conditionRelatedPkFieldMap = new HashMap<String, Object>();
                            for (String pkRelatedField : relatedEntity.getPkFieldNames()) {
                                conditionRelatedPkFieldMap.put(pkRelatedField, parameters.get(pkRelatedField));
                            }
                            GenericValue previousStatus = EntityQuery.use(newEntity.getDelegator()).from(modelEntity.getEntityName())
                                    .where(conditionRelatedPkFieldMap).orderBy("-statusDate").queryFirst();
                            if (previousStatus != null) {
                                previousStatus.put("statusEndDate", newEntity.get("statusDate"));
                                previousStatus.store();
                            }
                        }
                    }
                }
            }
        }
        newEntity.create();
        result.put("crudValue", newEntity);
        return result;
    }

    private static Map<String, Object> invokeUpdate(DispatchContext dctx, Map<String, Object> parameters, ModelService modelService, ModelEntity modelEntity, boolean allPksInOnly)
            throws GeneralException {
        Locale locale = (Locale) parameters.get("locale");
        Map<String, Object> localContext = new HashMap<String, Object>();
        localContext.put("parameters", parameters);
        Map<String, Object> result = ServiceUtil.returnSuccess();
        /*
         <auto-attributes include="pk" mode="IN" optional="false"/>
         *
         <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
         <set-nonpk-fields value-name="lookedUpValue" map-name="parameters"/>
         <store-value value-name="lookedUpValue"/>
         */

        // check to make sure that all primary key fields are defined as IN attributes
        if (!allPksInOnly) {
            throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the update invoke option not all pk fields have the mode IN");
        }

        GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
        if (lookedUpValue == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueNotFound", locale));
        }

        //        localContext.put("lookedUpValue", lookedUpValue);

        // populate the oldStatusId out if there is a service parameter for it, and before we do the set non-pk fields
        /*
        <auto-attributes include="pk" mode="IN" optional="false"/>
        <attribute name="oldStatusId" type="String" mode="OUT" optional="false"/>
         *
        <field-to-result field-name="lookedUpValue.statusId" result-name="oldStatusId"/>
         */
        ModelParam statusIdParam = modelService.getParam("statusId");
        ModelField statusIdField = modelEntity.getField("statusId");
        ModelParam oldStatusIdParam = modelService.getParam("oldStatusId");
        if (statusIdParam != null && statusIdParam.isIn() && oldStatusIdParam != null && oldStatusIdParam.isOut() && statusIdField != null) {
            result.put("oldStatusId", lookedUpValue.get("statusId"));
        }

        // do the StatusValidChange check
        /*
         <if-compare-field field="lookedUpValue.statusId" operator="not-equals" to-field="parameters.statusId">
             <!-- if the record exists there should be a statusId, but just in case make it so it won't blow up -->
             <if-not-empty field="lookedUpValue.statusId">
                 <!-- if statusId change is not in the StatusValidChange list, complain... -->
                      <entity-one entity-name="StatusValidChange" value-name="statusValidChange" auto-field-map="false">
                     <field-map field-name="statusId" env-name="lookedUpValue.statusId"/>
                     <field-map field-name="statusIdTo" env-name="parameters.statusId"/>
                 </entity-one>
                 <if-empty field="statusValidChange">
                     <!-- no valid change record found? return an error... -->
                          <add-error><fail-property resource="CommonUiLabels" property="CommonErrorNoStatusValidChange"/></add-error>
                     <check-errors/>
                 </if-empty>
             </if-not-empty>
         </if-compare-field>
         */
        String parameterStatusId = (String) parameters.get("statusId");
        if (statusIdParam != null && statusIdParam.isIn() && UtilValidate.isNotEmpty(parameterStatusId) && statusIdField != null) {
            String lookedUpStatusId = (String) lookedUpValue.get("statusId");
            if (UtilValidate.isNotEmpty(lookedUpStatusId) && !parameterStatusId.equals(lookedUpStatusId)) {
                // there was an old status, and in this call we are trying to change it, so do the StatusValidChange check
                GenericValue statusValidChange = dctx.getDelegator().findOne("StatusValidChange", true, "statusId", lookedUpStatusId, "statusIdTo", parameterStatusId);
                if (statusValidChange == null) {
                    // uh-oh, no valid change...
                    return ServiceUtil.returnError(UtilProperties.getMessage("CommonUiLabels", "CommonErrorNoStatusValidChange", localContext, locale));
                }
            }
        }
        // NOTE: nothing here to maintain the status history, that should be done with a custom service called by SECA rule

        lookedUpValue.setNonPKFields(parameters, true);
        if (modelEntity.getField("lastModifiedDate") != null
                || modelEntity.getField("changedDate") != null) {
            if (modelEntity.getField("lastModifiedDate") != null) {
                lookedUpValue.set("lastModifiedDate", UtilDateTime.nowTimestamp());
            } else {
                lookedUpValue.set("changedDate", UtilDateTime.nowTimestamp());
            }
            if (modelEntity.getField("lastModifiedByUserLogin") != null
                    || modelEntity.getField("changedByUserLogin") != null) {
                GenericValue userLogin = (GenericValue) parameters.get("userLogin");
                if (userLogin != null) {
                    if (modelEntity.getField("lastModifiedByUserLogin") != null) {
                        lookedUpValue.set("lastModifiedByUserLogin", userLogin.get("userLoginId"));
                    } else {
                        lookedUpValue.set("changedByUserLogin", userLogin.get("userLoginId"));
                    }
                }
            }
        }

        if (modelEntity.getField("changeByUserLoginId") != null ) {
            if (modelEntity.getEntityName().endsWith("Status")) {
                //Oh update on EntityStatus concept detected ... not possible, return invalid request
                throw new GenericServiceException("You call a updating operation on entity that track the activity, sorry I can't do that, please amazing developer check your service definition ;)");
            }
            GenericValue userLogin = (GenericValue) parameters.get("userLogin");
            if (userLogin != null) {
                lookedUpValue.set("changeByUserLoginId", userLogin.get("userLoginId"));
            } else {
                throw new GenericServiceException("You call a updating operation on entity that track the activity, sorry I can't do that, please amazing developer check your service definition ;)");
            }
        }

        lookedUpValue.store();
        result.put("crudValue", lookedUpValue);
        return result;
    }

    private static Map<String, Object> invokeDelete(DispatchContext dctx, Map<String, Object> parameters, ModelService modelService, ModelEntity modelEntity, boolean allPksInOnly)
            throws GeneralException {
        Locale locale = (Locale) parameters.get("locale");
        /*
        <auto-attributes include="pk" mode="IN" optional="false"/>
         *
        <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
        <remove-value value-name="lookedUpValue"/>
         */

        // check to make sure that all primary key fields are defined as IN attributes
        if (!allPksInOnly) {
            throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the delete invoke option not all pk fields have the mode IN");
        }

        if (modelEntity.getField("changeByUserLoginId") != null ) {
            if (modelEntity.getEntityName().endsWith("Status")) {
                //Oh update on EntityStatus concept detected ... not possible, return invalid request
                throw new GenericServiceException("You call a deleting operation on entity that track the activity, sorry I can't do that, please amazing developer check your service definition ;)");
            }
        }

        GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
        if (lookedUpValue == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueNotFoundForRemove", locale));
        }
        lookedUpValue.remove();
        return ServiceUtil.returnSuccess();
    }

    /**
     * Analyse the entity, service and parameter to resolve the field to update with what value
     * @param dctx
     * @param parameters
     * @param modelService
     * @param modelEntity
     * @param lookedUpValue
     * @param allPksInOnly
     * @return
     * @throws GeneralException
     */
    private static Map<String, Object> invokeExpire(DispatchContext dctx, Map<String, Object> parameters, ModelService modelService, ModelEntity modelEntity, boolean allPksInOnly)
            throws GeneralException {
        Locale locale = (Locale) parameters.get("locale");
        List<String> fieldThruDates = new LinkedList<String>();
        boolean thruDatePresent = false;
        String fieldDateNameIn = null;

        // check to make sure that all primary key fields are defined as IN attributes
        if (!allPksInOnly) {
            throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the update invoke option not all pk fields have the mode IN");
        }
        GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false, true, null, null);
        if (lookedUpValue == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceValueNotFound", locale));
        }

        //check if a non pk date field is present on parameters
        for (String fieldDateName : modelEntity.getNoPkFieldNames()) {
            if ("thruDate".equals(fieldDateName)) {
                thruDatePresent = true;
            } else if (fieldDateName.endsWith("ThruDate")) {
                fieldThruDates.add(fieldDateName);
            } else if (fieldDateName.startsWith("thru") && fieldDateName.endsWith("Date")) {
                fieldThruDates.add(fieldDateName);
            } else if (fieldDateNameIn == null && modelService.getParam(fieldDateName) != null
                    && modelEntity.getField(fieldDateName).getType().contains("date")) {
                fieldDateNameIn = fieldDateName;
            }
        }

        if (Debug.infoOn())
            Debug.logInfo(" FIELD FOUND : " + fieldDateNameIn + " ## # " + fieldThruDates + " ### " + thruDatePresent, module);

        if (Debug.infoOn())
            Debug.logInfo(" parameters IN  : " + parameters, module);
        // Resolve the field without value to expire and check if the value is present on parameters or use now
        if (fieldDateNameIn != null) {
            if (parameters.get(fieldDateNameIn) == null) parameters.put(fieldDateNameIn, UtilDateTime.nowTimestamp());
        } else if (thruDatePresent && UtilValidate.isEmpty(lookedUpValue.getTimestamp("thruDate"))) {
            if (UtilValidate.isEmpty(parameters.get("thruDate"))) parameters.put("thruDate", UtilDateTime.nowTimestamp());
        } else {
            for (String fieldDateName: fieldThruDates) {
                if (UtilValidate.isEmpty(lookedUpValue.getTimestamp(fieldDateName))) {
                    if (UtilValidate.isEmpty(parameters.get(fieldDateName))) parameters.put(fieldDateName, UtilDateTime.nowTimestamp());
                    break;
                }
            }
        }
        if (Debug.infoOn())
            Debug.logInfo(" parameters OUT  : " + parameters, module);
        return ServiceUtil.returnSuccess();
    }
}
