/*
 * 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.sling.servlets.post.impl.helper;

import java.util.ArrayList;
import java.util.List;

import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.servlets.post.SlingPostConstants;

/**
 * Encapsulates all infos from the respective request parameters that are needed
 * to create the repository property
 */
public class RequestProperty {

    private static final RequestParameter[] EMPTY_PARAM_ARRAY = new RequestParameter[0];

    public static final String DEFAULT_IGNORE = SlingPostConstants.RP_PREFIX
        + "ignore";

    public static final String DEFAULT_NULL = SlingPostConstants.RP_PREFIX
        + "null";

    private final String path;

    private final String name;

    private final String parentPath;

    private RequestParameter[] values;

    private String[] stringValues;

    private String typeHint;

    private boolean hasMultiValueTypeHint;

    private RequestParameter[] defaultValues = EMPTY_PARAM_ARRAY;

    private boolean isDelete;

    private String repositoryResourcePath;

    private boolean isRepositoryResourceMove;

    private boolean ignoreBlanks;

    private boolean useDefaultWhenMissing;

    private boolean patch = false;

    private Chunk chunk;

    public RequestProperty(String path) {
        assert path.startsWith("/");
        this.path = ResourceUtil.normalize(path);
        this.parentPath = ResourceUtil.getParent(path);
        this.name = ResourceUtil.getName(path);
    }

    public String getTypeHint() {
        return typeHint;
    }

    public boolean hasMultiValueTypeHint() {
        return this.hasMultiValueTypeHint;
    }

    public void setTypeHintValue(String typeHint) {
        if ( typeHint != null && typeHint.endsWith("[]") ) {
            this.typeHint = typeHint.substring(0, typeHint.length() - 2);
            this.hasMultiValueTypeHint = true;
        } else {
            this.typeHint = typeHint;
            this.hasMultiValueTypeHint = false;
        }
    }

    public String getPath() {
        return path;
    }

    public String getName() {
        return name;
    }

    public String getParentPath() {
        return parentPath;
    }

    public boolean hasValues() {
        if (useDefaultWhenMissing && defaultValues != null && defaultValues.length > 0) {
            return true;
        } else {
            if (ignoreBlanks) {
                return (values != null && getStringValues().length > 0);
            } else {
                return values != null;
            }
        }
    }

    public RequestParameter[] getValues() {
        return values;
    }

    public void setValues(RequestParameter[] values) {
        this.values = values;
    }

    public RequestParameter[] getDefaultValues() {
        return defaultValues;
    }

    public void setDefaultValues(RequestParameter[] defaultValues) {
        if (defaultValues == null) {
            this.defaultValues = EMPTY_PARAM_ARRAY;
        } else {
            this.defaultValues = defaultValues;
        }
    }

    public boolean isFileUpload() {
        return values != null && !values[0].isFormField();
    }

    /**
     * Checks if this property provides any values. this is the case if one of
     * the values is not empty or if the default handling is not 'ignore'
     *
     * @return <code>true</code> if this property provides values
     */
    public boolean providesValue() {
        // should void double creation of string values
        String[] sv = getStringValues();
        if (sv == null) {
            // is missleading return type. but means that property should not
            // get auto-create values
            return true;
        }
        for (String s : sv) {
            if (!s.equals("")) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the assembled string array out of the provided request values and
     * default values.
     *
     * @return a String array or <code>null</code> if the property needs to be
     *         removed.
     */
    public String[] getStringValues() {
        if (stringValues == null) {
            if (values == null && useDefaultWhenMissing) {
                stringValues = new String[] { defaultValues[0].getString() };
            } else if (values.length > 1) {
                // TODO: how the default values work for MV props is not very
                // clear
                List<String> stringValueList = new ArrayList<String>(values.length);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i].getString();
                    if ((!ignoreBlanks) || value.length() > 0) {
                        stringValueList.add(value);
                    }
                }
                stringValues = stringValueList.toArray(new String[stringValueList.size()]);
            } else {
                String value = values[0].getString();
                if (value.equals("")) {
                    if (ignoreBlanks) {
                        return new String[0];
                    } else {
                        if (defaultValues.length == 1) {
                            String defValue = defaultValues[0].getString();
                            if (defValue.equals(DEFAULT_IGNORE)) {
                                // ignore means, do not create empty values
                                return new String[0];
                            } else if (defValue.equals(DEFAULT_NULL)) {
                                // null means, remove property if exist
                                return null;
                            }
                            value = defValue;
                        }
                    }
                }
                stringValues = new String[] { value };
            }
        }
        return stringValues;
    }

    /**
     * Specifies whether this property should be deleted before any new content
     * is to be set according to the values stored.
     *
     * @param isDelete <code>true</code> if the repository item described by
     *            this is to be deleted before any other operation.
     */
    public void setDelete(boolean isDelete) {
        this.isDelete = isDelete;
    }

    /**
     * Determine the deletion status of this item
     * @return <code>true</code> if the repository item described by this is
     * to be deleted before setting new content to it.
     */
    public boolean isDelete() {
        return isDelete;
    }

    /**
     * Sets the path of the repository item from which the content for this
     * property is to be copied or moved. The path may be relative in which case
     * it will be resolved relative to the absolute path of this property.
     *
     * @param sourcePath The path of the repository item to get the content from
     * @param isMove <code>true</code> if the source content is to be moved,
     *            otherwise the source content is copied from the repository
     *            item.
     */
    public void setRepositorySource(String sourcePath, boolean isMove) {

        // make source path absolute
        if (!sourcePath.startsWith("/")) {
            sourcePath = getParentPath() + "/" + sourcePath;
            sourcePath = ResourceUtil.normalize(sourcePath);
        }

        this.repositoryResourcePath = sourcePath;
        this.isRepositoryResourceMove = isMove;
    }

    /**
     * If this is a target of a move operation
     * @return <code>true</code> if the content of this property is to be set
     * by moving content from another repository item.
     *
     * @see #getRepositorySource()
     */
    public boolean hasRepositoryMoveSource() {
        return isRepositoryResourceMove;
    }

    /**
     * if this is the source of a copy action
     * @return <code>true</code> if the content of this property is to be set
     * by copying content from another repository item.
     *
     * @see #getRepositorySource()
     */
    public boolean hasRepositoryCopySource() {
        return getRepositorySource() != null && !hasRepositoryMoveSource();
    }

    /**
     * get the source of a copy or move operation
     * @return the absolute path of the repository item from which the content
     * for this property is to be copied or moved.
     *
     * @see #hasRepositoryCopySource()
     * @see #hasRepositoryMoveSource()
     * @see #setRepositorySource(String, boolean)
     */
    public String getRepositorySource() {
        return repositoryResourcePath;
    }

    public void setIgnoreBlanks(boolean b) {
        ignoreBlanks = b;
    }

    public void setUseDefaultWhenMissing(boolean b) {
        useDefaultWhenMissing = b;
    }

    public void setPatch(boolean b) {
        patch = b;
    }

    /**
     * determines if this property is handled as multi-value property
     * @return whether this property is to be handled as a multi-value property
     * seen as set.
     */
    public boolean isPatch() {
        return patch;
    }

    /**
     *  it this is a chunk upload?
     *  @return true if request is chunk upload.
     */
    public boolean isChunkUpload() {
        return chunk != null;
    }

    public Chunk getChunk() {
        return chunk;
    }

    public void setChunk(Chunk chunk) {
        this.chunk = chunk;
    }
}
