/*
 * 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.lang3.StringUtils;
import org.apache.sling.api.resource.ModifiableValueMap;
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.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.script.ScriptException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * pipe that writes to configured resource
 */
public class WritePipe extends BasePipe {
    private static final Logger logger = LoggerFactory.getLogger(WritePipe.class);
    public static final String RESOURCE_TYPE = RT_PREFIX + "write";
    Node confTree;
    private List<Resource> propertiesToRemove;
    Pattern addPatch = Pattern.compile("\\+\\[(.*)\\]");
    Pattern multi = Pattern.compile("\\[(.*)\\]");

    /**
     * public constructor
     * @param plumber plumber instance
     * @param resource configuration resource
     * @param upperBindings super pipe's bindings
     * @throws Exception bad configuration handling
     */
    public WritePipe(Plumber plumber, Resource resource, PipeBindings upperBindings) throws Exception {
        super(plumber, resource, upperBindings);
        if (getConfiguration() == null){
            String pathCandidate = getExpr();
            if (StringUtils.isNotBlank(pathCandidate) && resolver.getResource(pathCandidate) != null){
                confTree = resolver.getResource(pathCandidate).adaptTo(Node.class);
            } else {
                throw new Exception("write pipe is misconfigured: it should have a configuration node, or an expression");
            }
        } else {
            confTree = getConfiguration().adaptTo(Node.class);
        }
    }


    /**
     * convert the configured string value (can be an expression) in a value that can be written in a resource.
     * also handles patch for multivalue properties like <code>+[value]</code> in which case <code>value</code>
     * is added to the MV property
     * @param resource resource to which value will be written
     * @param key property to which value will be written
     * @param expression configured value to write
     * @return actual value to write to the resource
     * @throws ScriptException in case value computation went wrong
     */
    protected Object computeValue(Resource resource, String key, String expression) throws ScriptException {
        Object value = bindings.instantiateObject((String) expression);
        if (value != null && value instanceof String) {
            //in that case we treat special case like MV or patches
            String sValue = (String)value;
            Matcher patch = addPatch.matcher(sValue);
            if (patch.matches()) {
                String newValue = patch.group(1);
                String[] actualValues = resource.adaptTo(ValueMap.class).get(key, String[].class);
                List<String> newValues = actualValues != null ? new LinkedList<>(Arrays.asList(actualValues)) : new ArrayList<String>();
                if (!newValues.contains(newValue)) {
                    newValues.add(newValue);
                }
                return newValues.toArray(new String[newValues.size()]);
            }
            Matcher multiMatcher = multi.matcher(sValue);
            if (multiMatcher.matches()) {
                return multiMatcher.group(1).split(",");
            }
        }
        return value;
    }

    /**
     * convert the configured string value (can be an expression) in a value that can be written in a resource.
     * also handles patch for multivalue properties like <code>+[value]</code> in which case <code>value</code>
     * is added to the MV property
     * @param resource resource to which value will be written
     * @param key property to which value will be written
     * @param expression configured value to write
     * @return actual value to write to the resource
     */
    protected Object computeValue(Resource resource, String key, Object expression) throws ScriptException {
        if (expression instanceof String) {
            return computeValue(resource, key, (String)expression);
        } else if (expression instanceof String[]){
            List<String> values = new ArrayList<>();
            for (String expr : (String[])expression){
                values.add((String)computeValue(resource, key, expr));
            }
            return values.toArray(new String[values.size()]);
        }
        return expression;
    }

    @Override
    public boolean modifiesContent() {
        return true;
    }

    /**
     * Write properties from the configuration to the target resource,
     * instantiating both property names & values
     *
     * @param conf configured resource that holds all properties to write (and subpipes)
     * @param target target resource on which configured values will be written
     * @throws RepositoryException issues occuring when traversing nodes
     */
    private void copyProperties(Resource conf, Resource target) throws ScriptException {
        ValueMap writeMap = conf.adaptTo(ValueMap.class);
        ModifiableValueMap properties = target.adaptTo(ModifiableValueMap.class);

        //writing current node
        if (properties != null && writeMap != null) {
            for (Map.Entry<String, Object> entry : writeMap.entrySet()) {
                if (!IGNORED_PROPERTIES.contains(entry.getKey())) {
                    String key = parent != null ? bindings.instantiateExpression(entry.getKey()) : entry.getKey();
                    Object value = computeValue(target, key, entry.getValue());
                    if (value == null) {
                        //null value are not handled by modifiable value maps,
                        //removing the property if it exists
                        addPropertyToRemove(target.getChild(key));
                    } else {
                        logger.info("writing {}={}",target.getPath() + "@" + key, value);
                        if (!isDryRun()){
                            properties.put(key, value);
                        }
                    }
                }
            }
        }
    }

    /**
     * we store all property to remove for very last moment (in order to potentially reuse their value)
     * @param property property resource that should be removed
     */
    private void addPropertyToRemove(Resource property){
        if (property != null) {
            if (propertiesToRemove == null) {
                propertiesToRemove = new ArrayList<>();
            }
            propertiesToRemove.add(property);
        }
    }

    /**
     * write the configured tree at the target resource, creating each node if needed, copying values.
     * @param conf configuration JCR tree to write to target resource
     * @param target target resource to write
     */
    private void writeTree(Node conf, Resource target) throws RepositoryException, ScriptException {
        copyProperties(resolver.getResource(conf.getPath()), target);
        NodeIterator childrenConf = conf.getNodes();
        if (childrenConf.hasNext()){
            Node targetNode = target.adaptTo(Node.class);
            logger.info("dubbing {} at {}", conf.getPath(), target.getPath());
            while (childrenConf.hasNext()){
                Node childConf = childrenConf.nextNode();
                String name = childConf.getName();
                name = bindings.instantiateExpression(name);
                if (!isDryRun()){
                    Node childTarget = targetNode.hasNode(name) ? targetNode.getNode(name) : targetNode.addNode(name, childConf.getPrimaryNodeType().getName());
                    logger.debug("writing tree {}", childTarget.getPath());
                    writeTree(childConf, resolver.getResource(childTarget.getPath()));
                }
            }
        }
    }


    @Override
    protected Iterator<Resource> computeOutput() throws Exception {
        try {
            Resource resource = getInput();
            if (resource != null) {
                writeTree(confTree, resource);
                if (propertiesToRemove != null && !propertiesToRemove.isEmpty()){
                    for (Resource propertyResource : propertiesToRemove) {
                        logger.info("removing {}", propertyResource.getPath());
                        if (!isDryRun()){
                            Property property = propertyResource.adaptTo(Property.class);
                            if (property != null) {
                                property.remove();
                            }
                        }
                    }
                }
                return super.computeOutput();
            }
        } finally {
            if (propertiesToRemove != null){
                propertiesToRemove.clear();
            }
        }
        return EMPTY_ITERATOR;
    }
}
