/*
 * 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.pipes.internal;

import org.apache.commons.collections.IteratorUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.pipes.BasePipe;
import org.apache.sling.pipes.PipeBindings;
import org.apache.sling.pipes.Plumber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Traverse either nodes or properties, in breadth first or depth first, for properties, they can be white listed
 */
public class TraversePipe extends BasePipe {
    private static final Logger LOGGER = LoggerFactory.getLogger(TraversePipe.class);
    public static final String RESOURCE_TYPE = RT_PREFIX + "traverse";

    /**
     * Pipe Constructor
     *
     * @param plumber  plumber
     * @param resource configuration resource
     * @param upperBindings super pipe's bindings
     */
    public TraversePipe(Plumber plumber, Resource resource, PipeBindings upperBindings) {
        super(plumber, resource, upperBindings);
    }


    @Override
    protected Iterator<Resource> computeOutput() {
        return new TraversingIterator(getInput(), getResource().getValueMap());
    }

    /**
     * iterative DFS or BFS jcr node tree iterator, transforming each visited node in a configured set of resources
     */
    public class TraversingIterator implements Iterator<Resource>{
        protected static final String PN_PROPERTIES = "properties";
        protected static final String PN_NAMEGLOBS = "nameGlobs";
        protected static final String PN_BREADTH = "breadthFirst";
        protected static final String PN_DEPTH = "depth";
        boolean properties;
        int initialLevel;
        int maxLevel;
        String[] nameGlobs;
        boolean breadthFirst;
        Iterator<Resource> currentResources;
        List<Node> nodesToVisit = new ArrayList<>();

        /**
         * From a given node, refresh resources extracted out of it depending on configuration
         * @param node
         * @throws RepositoryException
         */
        void refreshResourceIterator(Node node) throws RepositoryException {
            if (properties){
                PropertyIterator it = nameGlobs != null ? node.getProperties(nameGlobs) : node.getProperties();
                currentResources = IteratorUtils.transformedIterator(it, o -> {
                    try {
                        return resolver.getResource(((Property) o).getPath());
                    } catch (RepositoryException e) {
                        LOGGER.error("unable to read property", e);
                    }
                    return null;
                });
            } else {
                currentResources = IteratorUtils.singletonIterator(resolver.getResource(node.getPath()));
            }
        }

        int getDepth(String path) {
            return path.split("/").length;
        }

        boolean isBeforeLastLevel(Node node) throws RepositoryException {
            return maxLevel < 0 || getDepth(node.getPath()) < maxLevel;
        }

        /**
         * Constructor with root node, & configuration
         * @param root
         * @param configuration
         */
        TraversingIterator(Resource root, ValueMap configuration){
            properties = configuration.get(PN_PROPERTIES, false);
            if (properties) {
                nameGlobs = configuration.get(PN_NAMEGLOBS, String[].class);
            }
            breadthFirst = configuration.get(PN_BREADTH, false);
            maxLevel = configuration.get(PN_DEPTH, -1);
            if (maxLevel > 0){
                initialLevel = getDepth(root.getPath());
                maxLevel = initialLevel + maxLevel;
            }
            nodesToVisit.add(root.adaptTo(Node.class));
        }

        /**
         * Navigate up to the next node that have resources out of it
         * @return
         */
        boolean goToNextElligibleNode() {
            try {
                while ((currentResources == null || !currentResources.hasNext()) && !nodesToVisit.isEmpty()) {
                    Node node = nodesToVisit.remove(0);
                    LOGGER.debug("visiting {}", node.getPath());
                    refreshResourceIterator(node);
                    int indexAdd = breadthFirst ? nodesToVisit.size() : 0;
                    if (isBeforeLastLevel(node)) {
                        nodesToVisit.addAll(indexAdd, IteratorUtils.toList(node.getNodes()));
                    }
                }
            } catch (RepositoryException e) {
                LOGGER.error("unable to read node subpipes", e);
            }
            return currentResources != null && currentResources.hasNext();
        }

        @Override
        public boolean hasNext() {
            return (currentResources != null && currentResources.hasNext()) || goToNextElligibleNode();
        }

        @Override
        public Resource next() {
            return currentResources.next();
        }
    }
}
