/*
 * 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.testing.mock.sling.builder;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.JcrConstants;
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.testing.mock.osgi.MapUtil;
import org.jetbrains.annotations.NotNull;

/**
 * Helper class for building test content in the resource hierarchy with as less
 * boilerplate code as possible.
 */
public class ContentBuilder {

    static final String DUMMY_TEMPLATE = "/apps/sample/templates/template1";

    /**
     * Resource resolver
     */
    protected final ResourceResolver resourceResolver;

    /**
     * @param resourceResolver Resource resolver
     */
    public ContentBuilder(@NotNull ResourceResolver resourceResolver) {
        this.resourceResolver = resourceResolver;
    }

    /**
     * Create resource. If parent resource(s) do not exist they are created
     * automatically using <code>nt:unstructured</code> nodes.
     * @param path Page path
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull String path) {
        return resource(path, ValueMap.EMPTY);
    }

    /**
     * Create resource. If parent resource(s) do not exist they are created
     * automatically using <code>nt:unstructured</code> nodes.
     * @param path Page path
     * @param properties Properties for resource.
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull String path, @NotNull Map<String, Object> properties) {
        String parentPath = ResourceUtil.getParent(path);
        if (parentPath == null) {
            throw new IllegalArgumentException("Path has no parent: " + path);
        }

        // check if properties map contains maps representing child resources
        Map<String,Object> propertiesWihtoutChildren;
        Map<String,Map<String,Object>> children = getChildMaps(properties);
        if (!children.isEmpty()) {
            propertiesWihtoutChildren = new HashMap<>();
            for (Map.Entry<String, Object> entry : properties.entrySet()) {
                if (!children.containsKey(entry.getKey())) {
                    propertiesWihtoutChildren.put(entry.getKey(), entry.getValue());
                }
            }
        }
        else {
            propertiesWihtoutChildren = properties;
        }

        // create resource
        Resource parentResource = ensureResourceExists(parentPath);
        String name = ResourceUtil.getName(path);
        Resource newResource;
        try {
            newResource = resourceResolver.create(parentResource, name, propertiesWihtoutChildren);
        } catch (PersistenceException ex) {
            throw new RuntimeException("Unable to create resource at " + path, ex);
        }

        // create child resources
        for (Map.Entry<String,Map<String,Object>> entry : children.entrySet()) {
            resource(newResource, entry.getKey(), entry.getValue());
        }

        return newResource;
    }

    @SuppressWarnings("unchecked")
    private Map<String,Map<String,Object>> getChildMaps(Map<String,Object> properties) {
        Map<String,Map<String,Object>> result = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            if (entry.getValue() instanceof Map) {
                result.put(entry.getKey(), (Map)entry.getValue());
            }
        }
        return result;
    }

    /**
     * Create resource. If parent resource(s) do not exist they are created
     * automatically using <code>nt:unstructured</code> nodes.
     * @param path Page path
     * @param properties Properties for resource.
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull String path, @NotNull Object @NotNull ... properties) {
        return resource(path, MapUtil.toMap(properties));
    }

    /**
     * Create child resource below the given parent resource.
     * @param resource Parent resource
     * @param name Child resource name
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull Resource resource, @NotNull String name) {
        return resource(resource, name, ValueMap.EMPTY);
    }

    /**
     * Create child resource below the given parent resource.
     * @param resource Parent resource
     * @param name Child resource name
     * @param properties Properties for resource.
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull Resource resource, @NotNull String name, @NotNull Map<String, Object> properties) {
        String path = resource.getPath() + "/" + StringUtils.stripStart(name, "/");
        return resource(path, properties);
    }

    /**
     * Create child resource below the given parent resource.
     * @param resource Parent resource
     * @param name Child resource name
     * @param properties Properties for resource.
     * @return Resource object
     */
    public final @NotNull Resource resource(@NotNull Resource resource, @NotNull String name, @NotNull Object @NotNull ... properties) {
        return resource(resource, name, MapUtil.toMap(properties));
    }

    /**
     * Ensure that a resource exists at the given path. If not, it is created
     * using <code>nt:unstructured</code> node type.
     * @param path Resource path
     * @return Resource at path (existing or newly created)
     */
    @SuppressWarnings("null")
    protected final @NotNull Resource ensureResourceExists(@NotNull String path) {
        if (StringUtils.isEmpty(path) || StringUtils.equals(path, "/")) {
            return resourceResolver.getResource("/");
        }
        Resource resource = resourceResolver.getResource(path);
        if (resource != null) {
            return resource;
        }
        String parentPath = ResourceUtil.getParent(path);
        if (parentPath == null) {
            throw new IllegalArgumentException("Path has no parent: " + path);
        }
        String name = ResourceUtil.getName(path);
        Resource parentResource = ensureResourceExists(parentPath);
        try {
            resource = resourceResolver.create(parentResource, name,
                    ImmutableValueMap.of(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED));
            resourceResolver.commit();
            return resource;
        } catch (PersistenceException ex) {
            throw new RuntimeException("Unable to create resource at " + path, ex);
        }
    }

}
