/*******************************************************************************
 * 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.ofbiz.webtools;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilHttp;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelField;
import org.ofbiz.entity.model.ModelFieldType;
import org.ofbiz.entity.model.ModelReader;
import org.ofbiz.security.Security;

/**
 * Web Event for doing updates on Generic Entities
 */
public class GenericWebEvent {

    public static final String module = GenericWebEvent.class.getName();
    public static final String err_resource = "WebtoolsErrorUiLabels";

    /** An HTTP WebEvent handler that updates a Generic entity
     *
     * @param request The HTTP request object for the current JSP or Servlet request.
     * @param response The HTTP response object for the current JSP or Servlet request.
     * @return Returns a String specifying the outcome state of the event. This is used to decide which event
     * to run next or which view to display. If null no event is run nor view displayed, allowing the event to
     * call a forward on a RequestDispatcher.
     */
    public static String updateGeneric(HttpServletRequest request, HttpServletResponse response) {
        String entityName = request.getParameter("entityName");
        Locale locale = UtilHttp.getLocale(request);

        if (entityName == null || entityName.length() <= 0) {
            String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.entity_name_not_specified", locale) + ".";
            request.setAttribute("_ERROR_MESSAGE_", errMsg);
            Debug.logWarning("[GenericWebEvent.updateGeneric] The entityName was not specified, but is required.", module);
            return "error";
        }

        Security security = (Security) request.getAttribute("security");
        Delegator delegator = (Delegator) request.getAttribute("delegator");

        if (security == null) {
            String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource,"genericWebEvent.security_object_not_found", locale) + ".";
            request.setAttribute("_ERROR_MESSAGE_", errMsg);
            Debug.logWarning("[updateGeneric] The security object was not found in the request, please check the control servlet init.", module);
            return "error";
        }
        if (delegator == null) {
            String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.delegator_object_not_found", locale) + ".";
            request.setAttribute("_ERROR_MESSAGE_", errMsg);
            Debug.logWarning("[updateGeneric] The delegator object was not found in the request, please check the control servlet init.", module);
            return "error";
        }

        ModelReader reader = delegator.getModelReader();
        ModelEntity entity = null;

        try {
            entity = reader.getModelEntity(entityName);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
        }

        String updateMode = request.getParameter("UPDATE_MODE");

        if (updateMode == null || updateMode.length() <= 0) {
            String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.update_mode_not_specified", locale) + ".";
            request.setAttribute("_ERROR_MESSAGE_", errMsg);
            Debug.logWarning("[updateGeneric] Update Mode was not specified, but is required; entityName: " + entityName, module);
            return "error";
        }

        // check permissions before moving on...
        if (!security.hasEntityPermission("ENTITY_DATA", "_" + updateMode, request.getSession()) &&
            !security.hasEntityPermission(entity.getPlainTableName(), "_" + updateMode, request.getSession())) {
                Map<String, String> messageMap = UtilMisc.toMap("updateMode", updateMode, "entityName", entity.getEntityName(), "entityPlainTableName", entity.getPlainTableName());
                String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.not_sufficient_permissions_01", messageMap, locale);
                errMsg += UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.not_sufficient_permissions_02", messageMap, locale) + ".";

                request.setAttribute("_ERROR_MESSAGE_", errMsg);
            // not really successful, but error return through ERROR_MESSAGE, so quietly fail
            return "error";
        }

        GenericValue findByEntity = delegator.makeValue(entityName);

        // get the primary key parameters...
        String errMsgPk = "";
        Iterator<ModelField> pksIter = entity.getPksIterator();
        while (pksIter.hasNext()) {
            String errMsg = "";
            ModelField field = pksIter.next();

            ModelFieldType type = null;
            try {
                type = delegator.getEntityFieldType(entity, field.getType());
            } catch (GenericEntityException e) {
                Debug.logWarning(e, module);
                Map<String, String> messageMap = UtilMisc.toMap("fieldType", field.getType());
                errMsg += UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.fatal_error_param", messageMap, locale) + ".";
            }

            String fval = request.getParameter(field.getName());
            if (UtilValidate.isNotEmpty(fval)) {
                try {
                    findByEntity.setString(field.getName(), fval);
                } catch (Exception e) {
                    Map<String, String> messageMap = UtilMisc.toMap("fval", fval);
                    errMsg = errMsg + "<li>" + field.getColName() + UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.conversion_failed", messageMap, locale) + type.getJavaType() + ".";
                    Debug.logWarning("[updateGeneric] " + field.getColName() + " conversion failed: \"" + fval + "\" is not a valid " + type.getJavaType() + "; entityName: " + entityName, module);
                }
            }
        }

        if (errMsgPk.length() > 0) {
            request.setAttribute("_ERROR_MESSAGE_", errMsgPk);
            return "error";
        }

        // if this is a delete, do that before getting all of the non-pk parameters and validating them
        if (updateMode.equals("DELETE")) {
            // Remove associated/dependent entries from other tables here
            // Delete actual main entity last, just in case database is set up to do a cascading delete, caches won't get cleared
            try {
                delegator.removeByPrimaryKey(findByEntity.getPrimaryKey());
            } catch (GenericEntityException e) {
                String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.delete_failed", locale) + ": " + e.toString();
                Debug.logWarning(e, errMsg, module);
                request.setAttribute("_ERROR_MESSAGE_", errMsg);
                return "error";
            }

            return "success";
        }

        // get the non-primary key parameters
        String errMsgNonPk = "";
        Iterator<ModelField> nopksIter = entity.getNopksIterator();
        while (nopksIter.hasNext()) {
            ModelField field = nopksIter.next();

            ModelFieldType type = null;
            try {
                type = delegator.getEntityFieldType(entity, field.getType());
            } catch (GenericEntityException e) {
                Debug.logWarning(e, module);
                Map<String, String> messageMap = UtilMisc.toMap("fieldType", field.getType());
                errMsgNonPk += UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.fatal_error_param", messageMap, locale) + ".";
            }

            String fval = request.getParameter(field.getName());
            if (UtilValidate.isNotEmpty(fval)) {
                try {
                    findByEntity.setString(field.getName(), fval);
                } catch (Exception e) {
                    Map<String, String> messageMap = UtilMisc.toMap("fval", fval);
                    errMsgNonPk += field.getColName() + UtilProperties.getMessage(GenericWebEvent.err_resource,
                            "genericWebEvent.conversion_failed", messageMap, locale) + type.getJavaType() + ".";
                    Debug.logWarning("[updateGeneric] " + field.getColName() + " conversion failed: \"" + fval + "\" is not a valid " + type.getJavaType() + "; entityName: " + entityName, module);
                }
            } else {
                findByEntity.set(field.getName(), null);
            }
        }

        if (errMsgNonPk.length() > 0) {
            request.setAttribute("_ERROR_MESSAGE_", errMsgNonPk);
            return "error";
        }


        // if the updateMode is CREATE, check to see if an entity with the specified primary key already exists
        if (updateMode.equals("CREATE")) {
            GenericValue tempEntity = null;

            try {
                tempEntity = delegator.findOne(findByEntity.getEntityName(), findByEntity.getPrimaryKey(), false);
            } catch (GenericEntityException e) {
                String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.create_failed_by_check", locale) + ": " + e.toString();
                Debug.logWarning(e, errMsg, module);

                request.setAttribute("_ERROR_MESSAGE_", errMsg);
                return "error";
            }
            if (tempEntity != null) {
                Map<String, String> messageMap = UtilMisc.toMap("primaryKey", findByEntity.getPrimaryKey().toString());
                String errMsg = "[updateGeneric] " + entity.getEntityName() + UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.already_exists_pk", messageMap, locale)+ ".";
                Debug.logWarning(errMsg, module);
            }
        }

        // Validate parameters...
        String errMsgParam = "";
        Iterator<ModelField> fieldIter = entity.getFieldsIterator();
        while (fieldIter.hasNext()) {
            ModelField field = fieldIter.next();

            for (int j = 0; j < field.getValidatorsSize(); j++) {
                String curValidate = field.getValidator(j);
                Class<?>[] paramTypes = new Class[] {String.class};
                Object[] params = new Object[] {findByEntity.get(field.getName()).toString()};

                String className = "org.ofbiz.base.util.UtilValidate";
                String methodName = curValidate;

                if (curValidate.indexOf('.') > 0) {
                    className = curValidate.substring(0, curValidate.lastIndexOf('.'));
                    methodName = curValidate.substring(curValidate.lastIndexOf('.') + 1);
                }
                Class<?> valClass;

                try {
                    ClassLoader loader = Thread.currentThread().getContextClassLoader();
                    valClass = loader.loadClass(className);
                } catch (ClassNotFoundException cnfe) {
                    Debug.logError("[updateGeneric] Could not find validation class: " + className + "; ignoring.", module);
                    continue;
                }
                Method valMethod;

                try {
                    valMethod = valClass.getMethod(methodName, paramTypes);
                } catch (NoSuchMethodException cnfe) {
                    Debug.logError("[updateGeneric] Could not find validation method: " + methodName + " of class " + className + "; ignoring.", module);
                    continue;
                }

                Boolean resultBool;

                try {
                    resultBool = (Boolean) valMethod.invoke(null, params);
                } catch (Exception e) {
                    Debug.logError("[updateGeneric] Could not access validation method: " + methodName + " of class " + className + "; returning true.", module);
                    resultBool = Boolean.TRUE;
                }

                if (!resultBool.booleanValue()) {
                    Field msgField;
                    String message;

                    try {
                        msgField = valClass.getField(curValidate + "Msg");
                        message = (String) msgField.get(null);
                    } catch (Exception e) {
                        Debug.logError("[updateGeneric] Could not find validation message field: " + curValidate + "Msg of class " + className + "; returning generic validation failure message.", module);
                        message = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.validation_failed", locale) + ".";
                    }
                    errMsgParam += field.getColName() + " " + curValidate + " " + UtilProperties.getMessage(GenericWebEvent.err_resource,
                            "genericWebEvent.failed", locale) + ": " + message;

                    Debug.logWarning("[updateGeneric] " + field.getColName() + " " + curValidate + " failed: " + message, module);
                }
            }
        }

        if (errMsgParam.length() > 0) {
            errMsgParam = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.following_error_occurred", locale) + errMsgParam;
            request.setAttribute("_ERROR_MESSAGE_", errMsgParam);
            return "error";
        }

        if (updateMode.equals("CREATE")) {
            try {
                delegator.create(findByEntity.getEntityName(), findByEntity.getAllFields());
            } catch (GenericEntityException e) {
                Map<String, String> messageMap = UtilMisc.toMap("entityName", entity.getEntityName());
                String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.creation_param_failed", messageMap, locale)+ ": " + findByEntity.toString() + ": " + e.toString();
                Debug.logWarning(e, errMsg, module);
                request.setAttribute("_ERROR_MESSAGE_", errMsg);
                return "error";
            }
        } else if (updateMode.equals("UPDATE")) {
            GenericValue value = delegator.makeValue(findByEntity.getEntityName(), findByEntity.getAllFields());

            try {
                value.store();
            } catch (GenericEntityException e) {
                Map<String, String> messageMap = UtilMisc.toMap("entityName", entity.getEntityName());
                String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.update_of_param_failed", messageMap, locale)+ ": " + value.toString() + ": " + e.toString();
                Debug.logWarning(e, errMsg, module);
                request.setAttribute("_ERROR_MESSAGE_", errMsg);
                return "error";
            }
        } else {
            Map<String, String> messageMap = UtilMisc.toMap("updateMode", updateMode);
            String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.update_of_param_failed", messageMap, locale)+ ".";

            request.setAttribute("_ERROR_MESSAGE_", errMsg);
            Debug.logWarning("updateGeneric: Update Mode specified (" + updateMode + ") was not valid for entity: " + findByEntity.toString(), module);
            return "error";
        }

        return "success";
    }
}
