/*
 * 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.api.resource;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
 * The <code>ResourceMetadata</code> interface defines the API for the
 * metadata of a Sling {@link Resource}. Essentially the resource's metadata is
 * just a map of objects indexed by string keys.
 * <p>
 * The actual contents of the meta data map is implementation specific with the
 * exception of the {@link #RESOLUTION_PATH sling.resolutionPath} property which
 * must be provided by all implementations and contain the part of the request
 * URI used to resolve the resource. The type of this property value is defined
 * to be <code>String</code>.
 * <p>
 * Note, that the prefix <em>sling.</em> to key names is reserved for the
 * Sling implementation.
 *
 * Once a resource is returned by the {@link ResourceResolver}, the resource
 * metadata is made read-only and therefore can't be changed by client code!
 */
public class ResourceMetadata extends HashMap<String, Object> {

    private static final long serialVersionUID = 4692666752269523738L;

    /**
     * The name of the required property providing the part of the request URI
     * which was used to the resolve the resource to which the meta data
     * instance belongs (value is "sling.resolutionPath").
     */
    public static final String RESOLUTION_PATH = "sling.resolutionPath";

    /**
     * The name of the required property providing the part of the request URI
     * which was not used to the resolve the resource to which the meta data
     * instance belongs (value is "sling.resolutionPathInfo"). The value of this
     * property concatenated to the value of the
     * {@link #RESOLUTION_PATH sling.resolutionPath} property returns the
     * original request URI leading to the resource.
     * <p>
     * This property is optional. If missing, it should be assumed equal to an
     * empty string.
     *
     * @since 2.0.4 (Sling API Bundle 2.0.4)
     */
    public static final String RESOLUTION_PATH_INFO = "sling.resolutionPathInfo";

    /**
     * The name of the optional property providing the content type of the
     * resource if the resource is streamable (value is "sling.contentType").
     * This property may be missing if the resource is not streamable or if the
     * content type is not known.
     */
    public static final String CONTENT_TYPE = "sling.contentType";

    /**
     * The name of the optional property providing the content length of the
     * resource if the resource is streamable (value is "sling.contentLength").
     * This property may be missing if the resource is not streamable or if the
     * content length is not known.
     * <p>
     * Note, that unlike the other properties, this property may be set only
     * after the resource has successfully been adapted to an
     * <code>InputStream</code> for performance reasons.
     */
    public static final String CONTENT_LENGTH = "sling.contentLength";

    /**
     * The name of the optional property providing the character encoding of the
     * resource if the resource is streamable and contains character data (value
     * is "sling.characterEncoding"). This property may be missing if the
     * resource is not streamable or if the character encoding is not known.
     */
    public static final String CHARACTER_ENCODING = "sling.characterEncoding";

    /**
     * Returns the creation time of this resource in the repository in
     * milliseconds (value is "sling.creationTime"). The type of this property
     * is <code>java.lang.Long</code>. The property may be missing if the
     * resource is not streamable or if the creation time is not known.
     */
    public static final String CREATION_TIME = "sling.creationTime";

    /**
     * Returns the last modification time of this resource in the repository in
     * milliseconds (value is "sling.modificationTime"). The type of this
     * property is <code>java.lang.Long</code>. The property may be missing
     * if the resource is not streamable or if the last modification time is not
     * known.
     */
    public static final String MODIFICATION_TIME = "sling.modificationTime";

    /**
     * Returns whether the resource resolver should continue to search for a
     * resource.
     * A resource provider can set this flag to indicate that the resource
     * resolver should search for a provider with a lower priority. If it
     * finds a resource using such a provider, that resource is returned
     * instead. If none is found this resource is returned.
     * This flag should never be manipulated by application code!
     * The value of this property has no meaning, the resource resolver
     * just checks whether this flag is set or not.
     * @since 2.2 (Sling API Bundle 2.2.0)
     * @deprecated This flag is not supported anymore when implementing the SPI
     *             based {@code org.apache.sling.spi.resource.provider.ResourceProvider}
     */
    public static final String INTERNAL_CONTINUE_RESOLVING = ":org.apache.sling.resource.internal.continue.resolving";

    /**
     * Returns a map containing parameters added to path after semicolon.
     * For instance, map for path <code>/content/test;v='1.2.3'.html</code>
     * will contain one entry key <code>v</code> and value <code>1.2.3</code>.
     */
    public static final String PARAMETER_MAP = "sling.parameterMap";

    private boolean isReadOnly = false;

    /**
     * Sets the {@link #CHARACTER_ENCODING} property to <code>encoding</code>
     * if not <code>null</code>.
     * @param encoding The encoding
     */
    public void setCharacterEncoding(String encoding) {
        if (encoding != null) {
            put(CHARACTER_ENCODING, encoding);
        }
    }

    /**
     * Returns the {@link #CHARACTER_ENCODING} property if not <code>null</code>
     * and a <code>String</code> instance. Otherwise <code>null</code> is
     * returned.
     * @return The character encoding
     */
    public @CheckForNull String getCharacterEncoding() {
        Object value = get(CHARACTER_ENCODING);
        if (value instanceof String) {
            return (String) value;
        }

        return null;
    }

    /**
     * Sets the {@link #CONTENT_TYPE} property to <code>contentType</code> if
     * not <code>null</code>.
     * @param contentType The content type
     */
    public void setContentType(String contentType) {
        if (contentType != null) {
            put(CONTENT_TYPE, contentType);
        }
    }

    /**
     * Returns the {@link #CONTENT_TYPE} property if not <code>null</code> and
     * a <code>String</code> instance. Otherwise <code>null</code> is
     * returned.
     * @return The content type
     */
    public @CheckForNull String getContentType() {
        Object value = get(CONTENT_TYPE);
        if (value instanceof String) {
            return (String) value;
        }

        return null;
    }

    /**
     * Sets the {@link #CONTENT_LENGTH} property to <code>contentType</code>
     * if not <code>null</code>.
     * @param contentLength The content length
     */
    public void setContentLength(long contentLength) {
        if (contentLength > 0) {
            put(CONTENT_LENGTH, contentLength);
        }
    }

    /**
     * Returns the {@link #CONTENT_LENGTH} property if not <code>null</code>
     * and a <code>long</code>. Otherwise <code>-1</code> is returned.
     * @return The content length
     */
    public long getContentLength() {
        Object value = get(CONTENT_LENGTH);
        if (value instanceof Long) {
            return (Long) value;
        }

        return -1;
    }

    /**
     * Sets the {@link #CREATION_TIME} property to <code>creationTime</code>
     * if not negative.
     * @param creationTime The creation time
     */
    public void setCreationTime(long creationTime) {
        if (creationTime >= 0) {
            put(CREATION_TIME, creationTime);
        }
    }

    /**
     * Returns the {@link #CREATION_TIME} property if not <code>null</code>
     * and a <code>long</code>. Otherwise <code>-1</code> is returned.
     * @return The creation time
     */
    public long getCreationTime() {
        Object value = get(CREATION_TIME);
        if (value instanceof Long) {
            return (Long) value;
        }

        return -1;
    }

    /**
     * Sets the {@link #MODIFICATION_TIME} property to
     * <code>modificationTime</code> if not negative.
     * @param modificationTime The modification time
     */
    public void setModificationTime(long modificationTime) {
        if (modificationTime >= 0) {
            put(MODIFICATION_TIME, modificationTime);
        }
    }

    /**
     * Returns the {@link #MODIFICATION_TIME} property if not <code>null</code>
     * and a <code>long</code>. Otherwise <code>-1</code> is returned.
     * @return The modification time
     */
    public long getModificationTime() {
        Object value = get(MODIFICATION_TIME);
        if (value instanceof Long) {
            return (Long) value;
        }

        return -1;
    }

    /**
     * Sets the {@link #RESOLUTION_PATH} property to <code>resolutionPath</code>
     * if not <code>null</code>.
     * @param resolutionPath The resolution path
     */
    public void setResolutionPath(String resolutionPath) {
        if (resolutionPath != null) {
            put(RESOLUTION_PATH, resolutionPath);
        }
    }

    /**
     * Returns the {@link #RESOLUTION_PATH} property if not <code>null</code>
     * and a <code>String</code> instance. Otherwise <code>null</code> is
     * returned.
     * @return The resolution path
     */
    public @CheckForNull String getResolutionPath() {
        Object value = get(RESOLUTION_PATH);
        if (value instanceof String) {
            return (String) value;
        }

        return null;
    }

    /**
     * Sets the {@link #RESOLUTION_PATH_INFO} property to
     * <code>resolutionPathInfo</code> if not <code>null</code>.
     * @param resolutionPathInfo The resolution path info
     */
    public void setResolutionPathInfo(String resolutionPathInfo) {
        if (resolutionPathInfo != null) {
            put(RESOLUTION_PATH_INFO, resolutionPathInfo);
        }
    }

    /**
     * Returns the {@link #RESOLUTION_PATH_INFO} property if not
     * <code>null</code> and a <code>String</code> instance. Otherwise
     * <code>null</code> is returned.
     * @return The resolution path info
     */
    public @CheckForNull String getResolutionPathInfo() {
        Object value = get(RESOLUTION_PATH_INFO);
        if (value instanceof String) {
            return (String) value;
        }

        return null;
    }

    /**
     * Sets the {@link #PARAMETER_MAP} property to
     * <code>parameterMap</code> if not <code>null</code>.
     * @param parameterMap The parameter map
     */
    public void setParameterMap(Map<String, String> parameterMap) {
        if (parameterMap != null) {
            if (parameterMap.isEmpty()) {
                put(PARAMETER_MAP, Collections.emptyMap());
            } else {
                put(PARAMETER_MAP, new LinkedHashMap<String, String>(parameterMap));
            }
        }
    }

    /**
     * Returns the {@link #PARAMETER_MAP} property if not
     * <code>null</code> and a <code>Map</code> instance. Otherwise
     * <code>null</code> is returned.
     * @return The parameter map
     */
    @SuppressWarnings("unchecked")
    public @CheckForNull Map<String, String> getParameterMap() {
        Object value = get(PARAMETER_MAP);
        if (value instanceof Map) {
            return (Map<String, String>) value;
        }

        return null;
    }


    /**
     * Make this object read-only. All method calls trying to modify this object
     * result in an exception!
     * @since 2.3 (Sling API Bundle 2.4.0)
     */
    public void lock() {
        this.isReadOnly = true;
    }

    /**
     * Check if this object is read only and if so throw an unsupported operation exception.
     */
    private void checkReadOnly() {
        if ( this.isReadOnly ) {
            throw new UnsupportedOperationException(getClass().getSimpleName() + " is locked");
        }
    }

    @Override
    public void clear() {
        this.checkReadOnly();
        super.clear();
    }

    @Override
    public Object put(@Nonnull final String key, final Object value) {
        this.checkReadOnly();
        return super.put(key, value);
    }

    @Override
    public void putAll(@Nonnull final Map<? extends String, ? extends Object> m) {
        this.checkReadOnly();
        super.putAll(m);
    }

    @Override
    public Object remove(@Nonnull final Object key) {
        this.checkReadOnly();
        return super.remove(key);
    }

    protected void internalPut(@Nonnull String key, Object value) {
        super.put(key, value);
    }

    @Override
    public Object clone() {
        ResourceMetadata result = (ResourceMetadata) super.clone();
        result.lockedEntrySet = null;
        result.lockedKeySet = null;
        result.lockedValues = null;
        return result;
    }

	// volatile for correct double-checked locking in getLockedData()
    private transient volatile Set<Map.Entry<String, Object>> lockedEntrySet;
    private transient Set<String> lockedKeySet;
    private transient Collection<Object> lockedValues;

    private void getLockedData() {
        if(isReadOnly && lockedEntrySet == null) {
            synchronized (this) {
                if(isReadOnly && lockedEntrySet == null) {
                    lockedEntrySet = Collections.unmodifiableSet(super.entrySet());
                    lockedKeySet = Collections.unmodifiableSet(super.keySet());
                    lockedValues = Collections.unmodifiableCollection(super.values());
                }
            }
        }
    }

    @Override
    public @Nonnull Set<Map.Entry<String, Object>> entrySet() {
        getLockedData();
        return lockedEntrySet != null ? lockedEntrySet : super.entrySet();
    }

    @Override
    public @Nonnull Set<String> keySet() {
        getLockedData();
        return lockedKeySet != null ? lockedKeySet : super.keySet();
    }

    @Override
    public @Nonnull Collection<Object> values() {
        getLockedData();
        return lockedValues != null ? lockedValues : super.values();
    }
}
