/*******************************************************************************
 * 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.base.util.collections;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;

import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.string.FlexibleStringExpander;

/**
 * Used to flexibly access Map values, supporting the "." (dot) syntax for
 * accessing sub-map values and the "[]" (square bracket) syntax for accessing
 * list elements. See individual Map operations for more information.
 *
 */
@SuppressWarnings("serial")
public class FlexibleServletAccessor<T> implements Serializable {

    protected String name;
    protected String attributeName;
    protected FlexibleMapAccessor<T> fma;
    protected boolean needsExpand;
    protected boolean empty;

    public FlexibleServletAccessor(String name) {
        init(name);
    }

    public FlexibleServletAccessor(String name, String defaultName) {
        if (UtilValidate.isEmpty(name)) {
            init(defaultName);
        } else {
            init(name);
        }
    }

    protected void init(String name) {
        this.name = name;
        if (UtilValidate.isEmpty(name)) {
            empty = true;
            needsExpand = false;
            fma = FlexibleMapAccessor.getInstance(name);
            attributeName = name;
        } else {
            empty = false;
            int openPos = name.indexOf("${");
            if (openPos != -1 && name.indexOf("}", openPos) != -1) {
                fma = null;
                attributeName = null;
                needsExpand = true;
            } else {
                int dotIndex = name.indexOf('.');
                if (dotIndex != -1) {
                    attributeName = name.substring(0, dotIndex);
                    fma = FlexibleMapAccessor.getInstance(name.substring(dotIndex+1));
                } else {
                    attributeName = name;
                    fma = null;
                }

                needsExpand = false;
            }
        }
    }

    public boolean isEmpty() {
        return this.empty;
    }

    /** Based on name get from ServletRequest or from List in ServletRequest
     * @param request request to get the value from
     * @param expandContext the context to use for name expansion
     * @return the object corresponding to this getter class
     */
    public T get(ServletRequest request, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        return aa.get(request);
    }

    /** Based on name get from HttpSession or from List in HttpSession
     * @param session
     * @param expandContext
     * @return the found value
     */
    public T get(HttpSession session, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        return aa.get(session);
    }

    /** Based on name put in ServletRequest or from List in ServletRequest;
     * If the brackets for a list are empty the value will be appended to the list,
     * otherwise the value will be set in the position of the number in the brackets.
     * If a "+" (plus sign) is included inside the square brackets before the index
     * number the value will inserted/added at that point instead of set at the point.
     * @param request
     * @param value
     * @param expandContext
     */
    public void put(ServletRequest request, T value, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        aa.put(request, value);
    }

    /** Based on name put in HttpSession or from List in HttpSession;
     * If the brackets for a list are empty the value will be appended to the list,
     * otherwise the value will be set in the position of the number in the brackets.
     * If a "+" (plus sign) is included inside the square brackets before the index
     * number the value will inserted/added at that point instead of set at the point.
     * @param session
     * @param value
     * @param expandContext
     */
    public void put(HttpSession session, T value, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        aa.put(session, value);
    }

    /** Based on name remove from ServletRequest or from List in ServletRequest
     * @param request
     * @param expandContext
     * @return the removed value
     */
    public T remove(ServletRequest request, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        return aa.remove(request);
    }

    /** Based on name remove from HttpSession or from List in HttpSession
     * @param session
     * @param expandContext
     * @return the removed value
     */
    public T remove(HttpSession session, Map<String, Object> expandContext) {
        AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
        return aa.remove(session);
    }

    /** The equals and hashCode methods are imnplemented just case this object is ever accidently used as a Map key *
     * @return the hashcode
     */
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }

    /** The equals and hashCode methods are imnplemented just case this object is ever accidently used as a Map key
     * @param obj
     * @return whether this object is equal to the passed object
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof FlexibleServletAccessor<?>) {
            FlexibleServletAccessor<?> flexibleServletAccessor = (FlexibleServletAccessor<?>) obj;
            if (this.name == null) {
                return flexibleServletAccessor.name == null;
            }
            return this.name.equals(flexibleServletAccessor.name);
        } else {
            String str = (String) obj;
            if (this.name == null) {
                return str == null;
            }
            return this.name.equals(str);
        }
    }

    /** To be used for a string representation of the accessor, returns the original name.
     * @return the name of this accessor
     */
    @Override
    public String toString() {
        return this.name;
    }

    protected static class AttributeAccessor<T> implements Serializable {
        protected Map<String, Object> expandContext;
        protected String attributeName;
        protected FlexibleMapAccessor<T> fma;
        protected boolean isListReference;
        protected boolean isAddAtIndex;
        protected boolean isAddAtEnd;
        protected int listIndex;
        protected int openBrace;
        protected int closeBrace;

        public AttributeAccessor(String origName, Map<String, Object> expandContext, String defAttributeName, FlexibleMapAccessor<T> defFma, boolean needsExpand) {
            attributeName = defAttributeName;
            fma = defFma;

            if (needsExpand) {
                String name = FlexibleStringExpander.expandString(origName, expandContext);
                int dotIndex = name.indexOf('.');
                if (dotIndex != -1) {
                    attributeName = name.substring(0, dotIndex);
                    fma = FlexibleMapAccessor.getInstance(name.substring(dotIndex+1));
                } else {
                    attributeName = name;
                    fma = null;
                }
            }

            isListReference = false;
            isAddAtIndex = false;
            isAddAtEnd = false;
            listIndex = -1;
            openBrace = attributeName.indexOf('[');
            closeBrace = (openBrace == -1 ? -1 : attributeName.indexOf(']', openBrace));
            if (openBrace != -1 && closeBrace != -1) {
                String liStr = attributeName.substring(openBrace+1, closeBrace);
                //if brackets are empty, append to list
                if (liStr.length() == 0) {
                    isAddAtEnd = true;
                } else {
                    if (liStr.charAt(0) == '+') {
                        liStr = liStr.substring(1);
                        listIndex = Integer.parseInt(liStr);
                        isAddAtIndex = true;
                    } else {
                        listIndex = Integer.parseInt(liStr);
                    }
                }
                attributeName = attributeName.substring(0, openBrace);
                isListReference = true;
            }

        }

        public T get(ServletRequest request) {
            Object theValue = null;
            if (isListReference) {
                List<T> lst = UtilGenerics.cast(request.getAttribute(attributeName));
                theValue = lst.get(listIndex);
            } else {
                theValue = request.getAttribute(attributeName);
            }

            if (fma != null) {
                return fma.get(UtilGenerics.<String, Object>checkMap(theValue));
            } else {
                return UtilGenerics.<T>cast(theValue);
            }
        }

        public T get(HttpSession session) {
            Object theValue = null;
            if (isListReference) {
                List<T> lst = UtilGenerics.cast(session.getAttribute(attributeName));
                theValue = lst.get(listIndex);
            } else {
                theValue = session.getAttribute(attributeName);
            }

            if (fma != null) {
                return fma.get(UtilGenerics.<String, Object>checkMap(theValue));
            } else {
                return UtilGenerics.<T>cast(theValue);
            }
        }

        protected void putInList(List<T> lst, T value) {
            //if brackets are empty, append to list
            if (isAddAtEnd) {
                lst.add(value);
            } else {
                if (isAddAtIndex) {
                    lst.add(listIndex, value);
                } else {
                    lst.set(listIndex, value);
                }
            }
        }

        public void put(ServletRequest request, T value) {
            if (fma == null) {
                if (isListReference) {
                    List<T> lst = UtilGenerics.checkList(request.getAttribute(attributeName));
                    putInList(lst, value);
                } else {
                    request.setAttribute(attributeName, value);
                }
            } else {
                Object theObj = request.getAttribute(attributeName);
                if (isListReference) {
                    List<T> lst = UtilGenerics.checkList(theObj);
                    fma.put(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class), value);
                } else {
                    fma.put(UtilGenerics.checkMap(theObj, String.class, Object.class), value);
                }
            }
        }

        public void put(HttpSession session, T value) {
            if (fma == null) {
                if (isListReference) {
                    List<T> lst = UtilGenerics.checkList(session.getAttribute(attributeName));
                    putInList(lst, value);
                } else {
                    session.setAttribute(attributeName, value);
                }
            } else {
                Object theObj = session.getAttribute(attributeName);
                if (isListReference) {
                    List<T> lst = UtilGenerics.checkList(theObj);
                    fma.put(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class), value);
                } else {
                    fma.put(UtilGenerics.checkMap(theObj, String.class, Object.class), value);
                }
            }
        }

        public T remove(ServletRequest request) {
            if (fma != null) {
                Object theObj = request.getAttribute(attributeName);
                if (isListReference) {
                    List<Object> lst = UtilGenerics.checkList(theObj);
                    return fma.remove(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class));
                } else {
                    return fma.remove(UtilGenerics.checkMap(theObj, String.class, Object.class));
                }
            } else {
                if (isListReference) {
                    List<Object> lst = UtilGenerics.checkList(request.getAttribute(attributeName));
                    return UtilGenerics.<T>cast(lst.remove(listIndex));
                } else {
                    Object theValue = request.getAttribute(attributeName);
                    request.removeAttribute(attributeName);
                    return UtilGenerics.<T>cast(theValue);
                }
            }
        }

        public T remove(HttpSession session) {
            if (fma != null) {
                Object theObj = session.getAttribute(attributeName);
                if (isListReference) {
                    List<Object> lst = UtilGenerics.checkList(theObj);
                    return fma.remove(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class));
                } else {
                    return fma.remove(UtilGenerics.checkMap(theObj, String.class, Object.class));
                }
            } else {
                if (isListReference) {
                    List<Object> lst = UtilGenerics.checkList(session.getAttribute(attributeName));
                    return UtilGenerics.<T>cast(lst.remove(listIndex));
                } else {
                    Object theValue = session.getAttribute(attributeName);
                    session.removeAttribute(attributeName);
                    return UtilGenerics.<T>cast(theValue);
                }
            }
        }
    }
}
