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

import org.apache.commons.collections.keyvalue.DefaultKeyValue;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.pipes.AbstractInputStreamPipe;
import org.apache.sling.pipes.PipeBindings;
import org.apache.sling.pipes.Plumber;
import org.apache.sling.pipes.internal.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonStructure;
import javax.json.JsonValue.ValueType;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Pipe outputting binding related to a json stream: either an object
 */
public class JsonPipe extends AbstractInputStreamPipe {
    private static Logger logger = LoggerFactory.getLogger(JsonPipe.class);
    public static final String JSON_KEY = "json";
    public static final String RESOURCE_TYPE = RT_PREFIX + JSON_KEY;

    /**
     * property specifying the json path where to fetched the used value
     */
    protected static final String PN_VALUEPATH = "valuePath";

    /**
     * property specifying wether we should bind the computed json as a whole, or loop over it (not set or raw=false)
     */
    protected static final String PN_RAW = "raw";

    protected static final String JSONPATH_ROOT = "$";

    protected static final String ARRAY_START = "[";

    protected static final String OBJ_START = ".";

    protected static final Pattern JSONPATH_FIRSTTOKEN = Pattern.compile("^\\" + JSONPATH_ROOT + "([\\" + OBJ_START + "\\" + ARRAY_START + "])([^\\" + OBJ_START + "\\]\\" + ARRAY_START + "]+)\\]?");

    JsonBindingIterator internalIterator;

    public JsonPipe(Plumber plumber, Resource resource, PipeBindings upperBindings) {
        super(plumber, resource, upperBindings);
    }

    boolean isRaw() {
        if (properties.containsKey(PN_RAW)) {
            Object raw = bindings.instantiateObject(properties.get(PN_RAW, String.class));
            if (raw instanceof Boolean) {
                return (Boolean) raw;
            }
            return Boolean.parseBoolean((String)raw);
        }
        return false;
    }

    /**
     * in case there is no successful retrieval of some JSON data, we cut the pipe here
     * @return input resource of the pipe, can be reouputed N times in case output json binding is an array of
     * N element (output binding would be here each time the Nth element of the array)
     */
    public Iterator<Resource> getOutput(InputStream is) {
        Iterator<Resource> output = EMPTY_ITERATOR;
        Iterator<Resource> inputSingletonIterator = Collections.singleton(getInput()).iterator();
        try {
            String jsonString = IOUtils.toString(is, StandardCharsets.UTF_8);
            if (StringUtils.isNotBlank(jsonString)) {
                JsonStructure json;
                json = JsonUtil.parse(jsonString);
                if (json == null) {
                    binding = jsonString.trim();
                    output = inputSingletonIterator;
                } else {
                    String valuePath = properties.get(PN_VALUEPATH, String.class);
                    if (StringUtils.isNotBlank(valuePath)) {
                        json = getValue(json, bindings.instantiateExpression(valuePath));
                    }
                    if (isRaw() || !(json.getValueType() == ValueType.ARRAY || json.getValueType() == ValueType.OBJECT)) {
                        binding = JsonUtil.unbox(json);
                        output = inputSingletonIterator;
                    } else {
                        binding = json;
                        output = internalIterator = new JsonBindingIterator(json, getInput());
                    }
                }
            }
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
        return output;
    }

    class JsonBindingIterator implements Iterator<Resource> {
        Collection<Object> jsonValues;
        Iterator<Object> internal;
        final Resource inputResource;

        JsonBindingIterator(JsonStructure json, Resource inputResource) {
            jsonValues = json.getValueType() == ValueType.ARRAY ?
                    ((JsonArray) json).stream().map(JsonUtil::unbox).collect(Collectors.toList()):
                    ((JsonObject) json).entrySet().stream()
                            .map(e -> new DefaultKeyValue(e.getKey(),
                                    JsonUtil.unbox(e.getValue()))).collect(Collectors.toList());
            internal = jsonValues.iterator();
            this.inputResource = inputResource;
        }

        @Override
        public boolean hasNext() {
            return internal.hasNext();
        }

        @Override
        public Resource next() {
            if (! internal.hasNext()) {
                throw new NoSuchElementException();
            }
            binding = internal.next();
            return inputResource;
        }
    }

    /**
     * Returns fetched json value from value path
     * @param json json structure from which to start
     * @param valuePath path to follow
     * @return value fetched after following the path
     */
    protected JsonStructure getValue(JsonStructure json, String valuePath){
        Matcher matcher = JSONPATH_FIRSTTOKEN.matcher(valuePath);
        if (matcher.find()){
            String firstChar = matcher.group(1);
            String content = matcher.group(2);
            logger.trace("first char is {}, content is {}", firstChar, content);
            if (ARRAY_START.equals(firstChar)){
                JsonArray array = (JsonArray)json;
                int index = Integer.parseInt(content);
                json = (JsonStructure)array.get(index);
            } else if (OBJ_START.equals(firstChar)){
                JsonObject object = (JsonObject)json;
                json = (JsonStructure)object.get(content);
            }
            valuePath = StringUtils.removeStart(valuePath, matcher.group(0));
            if (StringUtils.isNotBlank(valuePath)){
                valuePath = JSONPATH_ROOT + valuePath;
                return getValue(json, valuePath);
            }
        }
        return json;
    }

}
