/*
 * 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.resourcebuilder.impl;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.resourcebuilder.api.ResourceBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/** ResourceBuilder implementation */
@SuppressWarnings("null")
public class ResourceBuilderImpl implements ResourceBuilder {
    private final @NotNull Resource originalParent;
    private final @NotNull ResourceResolver resourceResolver;
    private @NotNull Resource currentParent;
    private String intermediatePrimaryType;
    private boolean hierarchyMode;
    
    public static final String JCR_PRIMARYTYPE = "jcr:primaryType";
    public static final String JCR_MIMETYPE = "jcr:mimeType";
    public static final String JCR_LASTMODIFIED = "jcr:lastModified";
    public static final String JCR_DATA = "jcr:data";
    public static final String JCR_CONTENT = "jcr:content";
    public static final String NT_RESOURCE = "nt:resource";
    public static final String NT_FILE = "nt:file";
    
    public static final String CANNOT_RESTART =
            "Cannot reset the parent resource or resource resolver, please create a new "
            + "builder using the ResourceBuilder service";
    
    private final @NotNull MimeTypeService mimeTypeService;
    
    public ResourceBuilderImpl(@NotNull Resource parent, @NotNull MimeTypeService mts) {
        mimeTypeService = mts;
        if (parent == null) {
            throw new IllegalArgumentException("Parent resource is null");
        }
        originalParent = parent;
        resourceResolver = originalParent.getResourceResolver();
        intermediatePrimaryType = DEFAULT_PRIMARY_TYPE;
        currentParent = parent;
        hierarchyMode = true;
    }
    
    private @NotNull ResourceBuilderImpl cloneResourceBuilder(@NotNull Resource newCurrentParent,
            @Nullable String newIntermediatePrimaryType, boolean newHierarchyMode) {
        ResourceBuilderImpl clone = new ResourceBuilderImpl(originalParent, mimeTypeService);
        clone.currentParent = newCurrentParent;
        clone.intermediatePrimaryType = newIntermediatePrimaryType;
        clone.hierarchyMode = newHierarchyMode;
        return clone;
    }
    
    @Override
    public @NotNull Resource getCurrentParent() {
        return currentParent;
    }

    @Override
    public @NotNull ResourceBuilder atParent() {
        return cloneResourceBuilder(originalParent, this.intermediatePrimaryType, true);
    }
    
    private boolean isAbsolutePath(String path) {
        return path.startsWith("/") && !path.contains("..");
    }

    private void checkRelativePath(String path) {
        if(path.startsWith("/")) {
            throw new IllegalArgumentException("Path is not relative:" + path);
        }
        if(path.contains("..")) {
            throw new IllegalArgumentException("Path contains invalid pattern '..': " + path);
        }
    }

    private String parentPath(String relativePath) {
        final String parentPath = currentParent.getPath();
        final String fullPath = 
            parentPath.endsWith("/")  ? 
            parentPath + relativePath : 
            parentPath + "/" + relativePath;
        return ResourceUtil.getParent(fullPath);
    }
    
    @Override
    public @NotNull ResourceBuilder resource(@NotNull String path, @NotNull Map<String,Object> properties) {
        Resource r = null;
        
        final String parentPath;
        final String fullPath;
        boolean absolutePath = isAbsolutePath(path);
        if (absolutePath) {
            parentPath = ResourceUtil.getParent(path);
            fullPath = path;
        }
        else {
            checkRelativePath(path);
            parentPath = parentPath(path);
            fullPath = currentParent.getPath() + "/" + path;
        }
        final Resource myParent = ensureResourceExists(parentPath);
        
        try {
            r = currentParent.getResourceResolver().getResource(fullPath);
            if (r == null) {
                r = currentParent.getResourceResolver().create(myParent, 
                        ResourceUtil.getName(fullPath), properties);
            } else {
                // Resource exists, set our properties
                final ModifiableValueMap mvm = r.adaptTo(ModifiableValueMap.class);
                if (mvm == null) {
                    throw new IllegalStateException("Cannot modify properties of " + r.getPath());
                }
                for(Map.Entry <String, Object> e : properties.entrySet()) {
                    mvm.put(e.getKey(), e.getValue());
                }
            }
        } catch(PersistenceException pex) {
            throw new RuntimeException(
                    "PersistenceException while creating Resource " + fullPath, pex);
        }
        
        if (r == null) {
            throw new RuntimeException("Failed to get or create resource " + fullPath);
        } else if (hierarchyMode || absolutePath) {
            return cloneResourceBuilder(r, this.intermediatePrimaryType, true);
        }
        return this;
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public @NotNull ResourceBuilder resource(@NotNull String path, @NotNull Object @NotNull ... properties) {
        if (properties == null || properties.length == 0) {
            return resource(path, ValueMap.EMPTY);
        }
        else if (properties.length == 1 && properties[0] instanceof Map) {
            return resource(path, (Map<String,Object>)properties[0]);
        }
        else {
            return resource(path, MapArgsConverter.toMap(properties));
        }
    }
    
    /** Create a Resource at the specified path if none exists yet,
     *  using the current intermediate primary type. "Stolen" from
     *  the sling-mock module's ContentBuilder class.
     *  @param path Resource path
     *  @return Resource at path (existing or newly created)
     */
    protected final Resource ensureResourceExists(String path) {
        if(path == null || path.length() == 0 || path.equals("/")) {
            return resourceResolver.getResource("/");
        }
        Resource resource = resourceResolver.getResource(path);
        if (resource != null) {
            return resource;
        }
        String parentPath = ResourceUtil.getParent(path);
        String name = ResourceUtil.getName(path);
        Resource parentResource = ensureResourceExists(parentPath);
        try {
            resource = resourceResolver.create(
                    parentResource, 
                    name, 
                    MapArgsConverter.toMap(JCR_PRIMARYTYPE, intermediatePrimaryType));
            return resource;
        } catch (PersistenceException ex) {
            throw new RuntimeException("Unable to create intermediate resource at " + path, ex);
        }
    }
    
    protected String getMimeType(String filename, String userSuppliedMimeType) {
        if(userSuppliedMimeType != null) {
            return userSuppliedMimeType;
        }
        return mimeTypeService.getMimeType(filename);
    }
    
    protected long getLastModified(long userSuppliedValue) {
        if(userSuppliedValue < 0) {
            return System.currentTimeMillis();
        }
        return userSuppliedValue;
    }
    
    @Override
    public @NotNull ResourceBuilder file(@NotNull String relativePath, @NotNull InputStream data, @Nullable String mimeType, long lastModified) {
        checkRelativePath(relativePath);
        final String name = ResourceUtil.getName(relativePath);
        if(data == null) {
            throw new IllegalArgumentException("Data is null for file " + name);
        }
        
        Resource file = null;
        final ResourceResolver resolver = currentParent.getResourceResolver();
        final String parentPath = parentPath(relativePath);
        
        final Resource parent = ensureResourceExists(parentPath);
        try {
            final String fullPath = currentParent.getPath() + "/" + name;
            if(resolver.getResource(fullPath) != null) {
                throw new IllegalStateException("Resource already exists:" + fullPath);
            }
            final Map<String, Object> fileProps = new HashMap<String, Object>();
            fileProps.put(JCR_PRIMARYTYPE, NT_FILE);
            file = resolver.create(parent, name, fileProps);
            
            final Map<String, Object> contentProps = new HashMap<String, Object>();
            contentProps.put(JCR_PRIMARYTYPE, NT_RESOURCE);
            contentProps.put(JCR_MIMETYPE, getMimeType(name, mimeType));
            contentProps.put(JCR_LASTMODIFIED, getLastModified(lastModified));
            contentProps.put(JCR_DATA, data);
            resolver.create(file, JCR_CONTENT, contentProps); 
        } catch(PersistenceException pex) {
            throw new RuntimeException("Unable to create file under " + currentParent.getPath(), pex);
        }
        
        if(file == null) {
            throw new RuntimeException("Unable to get or created file resource " + relativePath + " under " + currentParent.getPath());
        }
        if(hierarchyMode) {
            return cloneResourceBuilder(file, this.intermediatePrimaryType, this.hierarchyMode);
        }
        return this;
    }

    @Override
    public @NotNull ResourceBuilder file(@NotNull String filename, @NotNull InputStream data) {
        return file(filename, data, null, -1);
    }

    @Override
    public @NotNull ResourceBuilder withIntermediatePrimaryType(@Nullable String primaryType) {
        String intermediatePrimaryType = primaryType == null ? DEFAULT_PRIMARY_TYPE : primaryType;
        return cloneResourceBuilder(currentParent, intermediatePrimaryType, hierarchyMode);
    }

    @Override
    public @NotNull ResourceBuilder siblingsMode() {
        return cloneResourceBuilder(currentParent, intermediatePrimaryType, false);
    }

    @Override
    public @NotNull ResourceBuilder hierarchyMode() {
        return cloneResourceBuilder(currentParent, intermediatePrimaryType, true);
    }
    
    @Override
    public @NotNull ResourceBuilder commit() {
        try {
            resourceResolver.commit();
        } catch (PersistenceException ex) {
            throw new RuntimeException("Unable to commit", ex);
        }
        return this;
    }

}
