/*******************************************************************************
 * 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.widget.renderer;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import org.apache.commons.collections4.MapUtils;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.collections.PagedList;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.util.EntityListIterator;
import org.apache.ofbiz.widget.WidgetWorker;
import org.apache.ofbiz.widget.model.ModelForm;

/**
 * Utility methods for handling list pagination.
 *
 */
public final class Paginator {

    public static final String module = Paginator.class.getName();

    public static int getActualPageSize(Map<String, Object> context) {
        Integer value = (Integer) context.get("actualPageSize");
        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
    }

    public static int getHighIndex(Map<String, Object> context) {
        Integer value = (Integer) context.get("highIndex");
        return value != null ? value.intValue() : 0;
    }

    public static void getListLimits(ModelForm modelForm, Map<String, Object> context, Object entryList) {
        int viewIndex = 0;
        int viewSize = 0;
        int lowIndex = 0;
        int highIndex = 0;
        int listSize = modelForm.getOverrideListSize(context);
        if (listSize > 0) {
            //setOverridenListSize(true);
        } else if (entryList instanceof EntityListIterator) {
            EntityListIterator iter = (EntityListIterator) entryList;
            try {
                listSize = iter.getResultsSizeAfterPartialList();
            } catch (GenericEntityException e) {
                Debug.logError(e, "Error getting list size", module);
                listSize = 0;
            }
        } else if (entryList instanceof List<?>) {
            List<?> items = (List<?>) entryList;
            listSize = items.size();
            if(context.containsKey("result")){
                Map<String, Object> resultMap = UtilGenerics.checkMap(context.get("result"));
                if(resultMap.containsKey("listSize")){
                    listSize = (int)resultMap.get("listSize");
                }
            }
        } else if (entryList instanceof PagedList) {
            PagedList<?> pagedList = (PagedList<?>) entryList;
            listSize = pagedList.getSize();
        }
        if (modelForm.getPaginate(context)) {
            viewIndex = getViewIndex(modelForm, context);
            viewSize = getViewSize(modelForm, context);
            lowIndex = viewIndex * viewSize;
            highIndex = (viewIndex + 1) * viewSize;
        } else {
            viewIndex = 0;
            viewSize = ModelForm.MAX_PAGE_SIZE;
            lowIndex = 0;
            highIndex = ModelForm.MAX_PAGE_SIZE;
        }
        context.put("listSize", Integer.valueOf(listSize));
        context.put("viewIndex", Integer.valueOf(viewIndex));
        context.put("viewSize", Integer.valueOf(viewSize));
        context.put("lowIndex", Integer.valueOf(lowIndex));
        context.put("highIndex", Integer.valueOf(highIndex));
    }

    public static int getListSize(Map<String, Object> context) {
        Integer value = (Integer) context.get("listSize");
        return value != null ? value.intValue() : 0;
    }

    public static int getLowIndex(Map<String, Object> context) {
        Integer value = (Integer) context.get("lowIndex");
        return value != null ? value.intValue() : 0;
    }

    public static int getViewIndex(ModelForm modelForm, Map<String, Object> context) {
        String field = modelForm.getMultiPaginateIndexField(context);
        int viewIndex = 0;
        try {
            Object value = context.get(field);
            if (value == null) {
                // try parameters.VIEW_INDEX as that is an old OFBiz convention
                Map<String, Object> parameters = UtilGenerics.cast(context.get("parameters"));
                if (parameters != null) {
                    value = parameters.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context));

                    if (value == null) {
                        value = parameters.get(field);
                    }
                }
            }
            // try paginate index field without paginator number
            if (value == null) {
                field = modelForm.getPaginateIndexField(context);
                value = context.get(field);
            }
            if (value instanceof Integer) {
                viewIndex = ((Integer) value).intValue();
            } else if (value instanceof String) {
                viewIndex = Integer.parseInt((String) value);
            }
        } catch (Exception e) {
            Debug.logWarning(e, "Error getting paginate view index: " + e.toString(), module);
        }
        return viewIndex;
    }

    public static int getViewSize(ModelForm modelForm, Map<String, Object> context) {
        String field = modelForm.getMultiPaginateSizeField(context);
        int viewSize = modelForm.getDefaultViewSize();
        try {
            Object value = context.get(field);
            if (value == null) {
                // try parameters.VIEW_SIZE as that is an old OFBiz convention
                Map<String, Object> parameters = UtilGenerics.cast(context.get("parameters"));
                if (parameters != null) {
                    value = parameters.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context));

                    if (value == null) {
                        value = parameters.get(field);
                    }
                }
            }
            // try the page size field without paginator number
            if (value == null) {
                field = modelForm.getPaginateSizeField(context);
                value = context.get(field);
            }
            if (value instanceof Integer) {
                viewSize = ((Integer) value).intValue();
            } else if (value instanceof String && UtilValidate.isNotEmpty(value)) {
                viewSize = Integer.parseInt((String) value);
            }
        } catch (Exception e) {
            Debug.logWarning(e, "Error getting paginate view size: " + e.toString(), module);
        }
        return viewSize;
    }

    public static void preparePager(ModelForm modelForm, Map<String, Object> context) {

        String lookupName = modelForm.getListName();
        if (UtilValidate.isEmpty(lookupName)) {
            Debug.logError("No value for list or iterator name found.", module);
            return;
        }
        Object obj = context.get(lookupName);
        if (obj == null) {
            if (Debug.verboseOn())
                Debug.logVerbose("No object for list or iterator name [" + lookupName + "] found, so not running pagination.",
                        module);
            return;
        }
        // if list is empty, do not render rows
        Iterator<?> iter = null;
        if (obj instanceof Iterator<?>) {
            iter = (Iterator<?>) obj;
        } else if (obj instanceof List<?>) {
            iter = ((List<?>) obj).listIterator();
        } else if (obj instanceof PagedList<?>) {
            iter = ((PagedList<?>) obj).iterator();
        }

        // set low and high index
        getListLimits(modelForm, context, obj);

        int listSize = ((Integer) context.get("listSize")).intValue();
        int lowIndex = ((Integer) context.get("lowIndex")).intValue();
        int highIndex = ((Integer) context.get("highIndex")).intValue();
        // Debug.logInfo("preparePager: low - high = " + lowIndex + " - " + highIndex, module);

        // we're passed a subset of the list, so use (0, viewSize) range
        if (modelForm.isOverridenListSize()) {
            lowIndex = 0;
            highIndex = ((Integer) context.get("viewSize")).intValue();
        }

        if (iter == null)
            return;

        // count item rows
        int itemIndex = -1;
        Object item = safeNext(iter);
        while (item != null && itemIndex < highIndex) {
            itemIndex++;
            item = safeNext(iter);
        }

        // Debug.logInfo("preparePager: Found rows = " + itemIndex, module);

        // reduce the highIndex if number of items falls short
        if ((itemIndex + 1) < highIndex) {
            highIndex = itemIndex + 1;
            // if list size is overridden, use full listSize
            context.put("highIndex", Integer.valueOf(modelForm.isOverridenListSize() ? listSize : highIndex));
        }
        context.put("actualPageSize", Integer.valueOf(highIndex - lowIndex));

        if (iter instanceof EntityListIterator) {
            try {
                ((EntityListIterator) iter).beforeFirst();
            } catch (GenericEntityException e) {
                Debug.logError(e, "Error rewinding list form render EntityListIterator: " + e.toString(), module);
            }
        }
    }

    private static <X> X safeNext(Iterator<X> iterator) {
        try {
            return iterator.next();
        } catch (NoSuchElementException e) {
            return null;
        }
    }

    /**
     * @param context Map
     * @param viewIndexName
     * @return value of viewIndexName in context map (as an int) or return 0 as default
     */
    public static Integer getViewIndex(final Map<String, ? extends Object> context, final String viewIndexName) {
        return getViewIndex(context, viewIndexName, 0);
    }

    /**
     * @param context
     * @param viewIndexName
     * @param defaultValue
     * @return value of viewIndexName in context map (as an int) or return defaultValue
     */
    public static Integer getViewIndex(final Map<String, ? extends Object> context, final String viewIndexName, final int defaultValue) {
        return MapUtils.getInteger(context, viewIndexName, defaultValue);
    }

    /**
     * @param context
     * @param viewSizeName
     * @return value of viewSizeName in context map (as an int) or return 
     *         default value from widget.properties
     */
    public static Integer getViewSize(Map<String, ? extends Object> context, String viewSizeName) {
        int defaultSize = UtilProperties.getPropertyAsInteger("widget", "widget.form.defaultViewSize", 20);
        if (context.containsKey(viewSizeName)) {
            return MapUtils.getInteger(context, viewSizeName, defaultSize);
        }
        return defaultSize;
    }

}
