/*
 * 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.sling.pipes.PipeBindings;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.apache.sling.pipes.PipeBindings.INJECTED_SCRIPT_REGEXP;

/**
 * utilities for user input
 */
public class CommandUtil {
    static final String PAIR_SEP = ",";
    static final String KEY_VALUE_SEP = "=";
    static final String FIRST_KEY = "first";
    static final String SECOND_KEY = "second";
    static final String PN_JCR_MIXIN = "jcr:mixinTypes";
    static final Pattern MIXINS_ARRAY_PATTERN = Pattern.compile("^\\s*\\[(.*)\\]\\s*$");
    private static final Pattern UNEMBEDDEDSCRIPT_PATTERN = Pattern.compile("^(\\d+(\\.\\d+)?)|" + //21.42
            "\\[.*]$|" + //['one','two']
            "[\\w_\\-]+\\..+|" + //map.field...
            "[\\w_\\-]+\\['.+']|" + //map['field']
            "true$|false$|" + //boolean
            "new .*|" + //instantiation
            "(.*'$)"); // 'string'
    static final String EXPR_TOKEN = "([^=]+|" + INJECTED_SCRIPT_REGEXP + ")+";
    static final String CONFIGURATION_TOKEN = "\\s*(?<" + FIRST_KEY + ">" + EXPR_TOKEN + ")\\s*" + KEY_VALUE_SEP
            + "\\s*(?<" + SECOND_KEY + ">(" + EXPR_TOKEN + ")+)\\s*";
    public static final Pattern CONFIGURATION_PATTERN = Pattern.compile(CONFIGURATION_TOKEN);

    private CommandUtil() {
    }

    /**
     * Checks arguments and throws exception if there is an issue
     * @param params arguments to check
     * @throws IllegalArgumentException exception thrown in case arguments are wrong
     */
    public static void checkArguments(Object... params) {
        if (params.length % 2 > 0){
            throw new IllegalArgumentException("there should be an even number of arguments");
        }
    }

    /**
     * @param value
     * @return eventually wrapped value
     */
    static Object embedIfNeeded(Object value) {
        if (value instanceof String) {
            Matcher matcher = UNEMBEDDEDSCRIPT_PATTERN.matcher(value.toString());
            if (matcher.matches()) {
                return PipeBindings.embedAsScript(value.toString());
            }
        }
        return value;
    }

    /**
     * write key/value pairs into a map
     * @param map target map
     * @param embed flag indicating wether or not we should try to embed values in script tags,
     * @param params key/value pairs to write into the map
     */
    public static void writeToMap(Map<String, Object> map, boolean embed, Object... params){
        for (int i = 0; i < params.length - 1; i += 2) {
            map.put(params[i].toString(), embed ? embedIfNeeded(params[i + 1]) : params[i + 1]);
            if (params[i].toString().equals(PN_JCR_MIXIN)) {
                map.put(PN_JCR_MIXIN, handleMixins((String)params[i + 1]));
            }
        }
    }

    static String[] handleMixins(String value) {
        Matcher matcher = MIXINS_ARRAY_PATTERN.matcher(value);
        if (matcher.matches()) {
            return Arrays.stream(matcher.group(1).split(PAIR_SEP))
                    .map(String::trim)
                    .collect(Collectors.toList()).toArray(new String[0]);
        }
        return new String[] { value };
    }

    /**
     * @param input comma separated key=value pairs
     * @param valueTransformer before adding it to the map, that function will be applied to found value
     * @return map of key and (transformed) value
     */
    public static Map<String, Object> stringToMap(@NotNull String input, UnaryOperator<String> valueTransformer) {
        Map<String, Object> map = new HashMap<>();
        for (String pair : input.split(PAIR_SEP) ){
            Matcher matcher = CONFIGURATION_PATTERN.matcher(pair);
            if (matcher.find()) {
                map.put(matcher.group(FIRST_KEY), valueTransformer.apply(matcher.group(SECOND_KEY)));
            }
        }
        return map;
    }

    /**
     * @param o list of key value strings key1=value1,key2=value2,...
     * @return String [] key1,value1,key2,value2,... corresponding to the pipe builder API
     */
    public static String[] keyValuesToArray(List<String> o) {
        List<String> args = new ArrayList<>();
        if (o != null) {
            for (String pair : o) {
                Matcher matcher = CONFIGURATION_PATTERN.matcher(pair.trim());
                if (matcher.matches()) {
                    args.add(matcher.group(FIRST_KEY));
                    args.add(matcher.group(SECOND_KEY));
                }
            }
        }
        return args.toArray(new String[args.size()]);
    }

}
