/*
 * 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.ki.web.attr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ki.KiException;
import org.apache.ki.util.ClassUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.beans.PropertyEditor;

/**
 * Convenient superclass for implementations of the {@link WebAttribute} interface.  This class encapsulates
 * converting values from a String form to Object form and vice versa through the use of a <tt>PropertyEditor</tt>
 * configured using {@link #setEditorClass(Class)}.  Subclasses are expected to implement the
 * {@link #onStoreValue(Object, javax.servlet.ServletRequest, javax.servlet.ServletResponse)} and
 * {@link #onRetrieveValue(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}
 * methods that perform the actual storing and retrieving of a String value.  This class also contains convenience
 * methods for retrieving the value of a request parameter to be stored.
 *
 * @author Les Hazlewood
 * @since 0.2
 */
public abstract class AbstractWebAttribute<T> implements WebAttribute<T> {

    //TODO - complete JavaDoc

    public static final String DEFAULT_NAME = "name";

    private static final Log log = LogFactory.getLog(AbstractWebAttribute.class);

    protected String name = DEFAULT_NAME;

    protected boolean checkRequestParams = true;
    protected boolean checkRequestParamsFirst = true;

    protected boolean mutable = true;

    /**
     * Property editor class to use to convert attributes to and from strings.
     */
    private Class<? extends PropertyEditor> editorClass = null;

    public AbstractWebAttribute() {
        this(DEFAULT_NAME, true);
    }

    public AbstractWebAttribute(String name) {
        this(name, true);
    }

    public AbstractWebAttribute(String name, boolean checkRequestParams) {
        setName(name);
        setCheckRequestParams(checkRequestParams);
    }

    public AbstractWebAttribute(String name, Class<? extends PropertyEditor> editorClass) {
        this(name, true, editorClass);
    }

    public AbstractWebAttribute(String name, boolean checkRequestParams, Class<? extends PropertyEditor> editorClass) {
        setName(name);
        setCheckRequestParams(checkRequestParams);
        setEditorClass(editorClass);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isCheckRequestParams() {
        return checkRequestParams;
    }

    public void setCheckRequestParams(boolean checkRequestParams) {
        this.checkRequestParams = checkRequestParams;
    }

    public boolean isCheckRequestParamsFirst() {
        return checkRequestParamsFirst;
    }

    public void setCheckRequestParamsFirst(boolean checkRequestParamsFirst) {
        this.checkRequestParamsFirst = checkRequestParamsFirst;
    }

    public Class<? extends PropertyEditor> getEditorClass() {
        return editorClass;
    }

    /**
     * If set, an instance of this class will be used to convert a the object value to a string value (and vice versa)
     * when reading and populating values in
     * {@link javax.servlet.http.HttpServletRequest HttpServletRequest}s, {@link javax.servlet.http.Cookie Cookie}s or
     * {@link javax.servlet.http.HttpSession HttpSession}s.
     *
     * <p>If not set, the string itself will be used.
     *
     * @param editorClass {@link PropertyEditor PropertyEditor} implementation used to
     *                    convert between string values and sessionId objects.
     */
    public void setEditorClass(Class<? extends PropertyEditor> editorClass) {
        this.editorClass = editorClass;
    }

    /**
     * Returns <tt>true</tt> if the value stored can be changed once it has been set, <tt>false</tt> if it cannot.
     * <p>Default is <tt>true</tt>.
     *
     * @return <tt>true</tt> if the value stored can be changed once it has been set, <tt>false</tt> if it cannot.
     */
    public boolean isMutable() {
        return mutable;
    }

    public void setMutable(boolean mutable) {
        this.mutable = mutable;
    }

    @SuppressWarnings({"unchecked"})
    protected T fromStringValue(String stringValue) {
        Class clazz = getEditorClass();
        if (clazz == null) {
            try {
                return (T) stringValue;
            } catch (Exception e) {
                String msg = "If the type is not String, you must specify the 'editorClass' property.";
                throw new KiException(msg, e);
            }
        } else {
            PropertyEditor editor = (PropertyEditor) ClassUtils.newInstance(getEditorClass());
            editor.setAsText(stringValue);
            Object value = editor.getValue();
            try {
                return (T) value;
            } catch (ClassCastException e) {
                String msg = "Returned value from PropertyEditor does not match the specified type.";
                throw new KiException(msg, e);
            }
        }
    }

    protected String toStringValue(T value) {
        Class clazz = getEditorClass();
        if (clazz == null) {

            if (log.isDebugEnabled()) {
                log.debug("No 'editorClass' property set - returning value.toString() as the string value for " +
                        "method argument.");
            }
            return value.toString();
        } else {
            PropertyEditor editor = (PropertyEditor) ClassUtils.newInstance(getEditorClass());
            editor.setValue(value);
            return editor.getAsText();
        }
    }

    protected T getFromRequestParam(ServletRequest request) {
        T value = null;

        String paramName = getName();
        String paramValue = request.getParameter(paramName);
        if (paramValue != null) {
            if (log.isTraceEnabled()) {
                log.trace("Found string value [" + paramValue + "] from HttpServletRequest parameter [" + paramName + "]");
            }
            value = fromStringValue(paramValue);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("No string value found in the HttpServletRequest under parameter named [" + paramName + "]");
            }
        }

        return value;
    }

    public final T retrieveValue(ServletRequest request, ServletResponse response) {
        T value = null;
        if (isCheckRequestParams() && isCheckRequestParamsFirst()) {
            value = getFromRequestParam(request);
        }

        if (value == null) {
            value = onRetrieveValue(request, response);
        }

        if (value == null) {
            if (isCheckRequestParams() && !isCheckRequestParamsFirst()) {
                value = getFromRequestParam(request);
            }
        }

        return value;
    }

    protected abstract T onRetrieveValue(ServletRequest request, ServletResponse response);

    public void storeValue(T value, ServletRequest request, ServletResponse response) {
        if (value == null && isMutable()) {
            removeValue(request, response);
            return;
        }

        if (!isMutable()) {
            Object existing = onRetrieveValue(request, response);
            if (existing != null) {
                if (log.isDebugEnabled()) {
                    log.debug("Found existing value stored under name [" + getName() + "].  Ignoring new " +
                            "storage request - this store is immutable after the value has initially been set.");
                }
            }
            return;
        }

        onStoreValue(value, request, response);
    }

    protected abstract void onStoreValue(T value, ServletRequest request, ServletResponse response);
}
