/*
 * 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.dubbo.admin.common.util;

import org.apache.dubbo.common.utils.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String parsing tools related to interpolation, including Glob mode, Query string, Service URL processing.
 *
 */
public class ParseUtils {

    private static final ConcurrentMap<String, Pattern>
        REPLACE_PARAMETER_PATTERNS = new ConcurrentHashMap<String, Pattern>();
    public static String METHOD_SPLIT = ",";
    private static Pattern VARIABLE_PATTERN = Pattern.compile(
            "\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?");
    private static Pattern QUERY_PATTERN = Pattern
            .compile("([&=]?)\\s*([^&=\\s]+)");

    private ParseUtils() {
    }

    /**
     * Execute interpolation (variable insertion).
     *
     * @param expression Expression string containing variables. Variable names in expressions can also be enclosed in <code> {} </ code>。
     * @param params Variable set. Variable names can include <code>. </ Code>, <code> _ </ code> characters.
     * @return After the completion of the interpolation string. Such as: <code> <pre> xxx $ {name} zzz -> xxxjerryzzz </ pre> </ code> (where the variable name = "jerry")
     * @throws IllegalStateException The variables used in the expression string are not in the variable set
     */
    // FIXME Is it reasonable to throw an IllegalStateException??
    public static String interpolate(String expression, Map<String, String> params) {
        if (expression == null || expression.length() == 0) {
            throw new IllegalArgumentException("glob pattern is empty!");
        }
        if (expression.indexOf('$') < 0) {
            return expression;
        }
        Matcher matcher = VARIABLE_PATTERN.matcher(expression);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) { // match one by one
            String key = matcher.group(1);
            String value = params == null ? null : params.get(key);
            if (value == null) {
                value = "";
            }
            matcher.appendReplacement(sb, value);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static List<String> interpolate(List<String> expressions, Map<String, String> params) {
        List<String> ret = new ArrayList<String>();

        if (null == expressions || expressions.isEmpty()) {
            return ret;
        }

        for (String expr : expressions) {
            ret.add(interpolate(expr, params));
        }

        return ret;
    }

    /**
     * Match Glob mode. The current implementation only supports <code>*</ code> and supports only one. Does not support <code>?</ Code>.
     * @return For code or value of <code> null </ code>, return <code> false </ code> directly.
     */
    public static boolean isMatchGlobPattern(String pattern, String value) {
        if ("*".equals(pattern))
            return true;
        if ((pattern == null || pattern.length() == 0)
                && (value == null || value.length() == 0))
            return true;
        if ((pattern == null || pattern.length() == 0)
                || (value == null || value.length() == 0))
            return false;

        int i = pattern.lastIndexOf('*');
        // No asterisk found
        if (i == -1) {
            return value.equals(pattern);
        }
        // Asterisk at the end
        else if (i == pattern.length() - 1) {
            return value.startsWith(pattern.substring(0, i));
        }
        // Asterisk at the beginning
        else if (i == 0) {
            return value.endsWith(pattern.substring(i + 1));
        }
        // Asterisk in the middle of the string
        else {
            String prefix = pattern.substring(0, i);
            String suffix = pattern.substring(i + 1);
            return value.startsWith(prefix) && value.endsWith(suffix);
        }
    }

    /**
     * Whether to match Glob mode. Glob mode is the expression to be interpolated. Glob pattern has more than one, as long as matching a pattern, that match is successful.
     *
     * @param patternsNeedInterpolate Multiple Glob patterns to interpolate
         * @param interpolateParams Set of variables used for interpolation
         * @param value Glob mode value
     */
    public static boolean isMatchGlobPatternsNeedInterpolate(
        Collection<String> patternsNeedInterpolate,
        Map<String, String> interpolateParams, String value) {
        if (patternsNeedInterpolate != null && !patternsNeedInterpolate.isEmpty()) {
            for (String patternNeedItp : patternsNeedInterpolate) {
                if (StringUtils.isEmpty(patternNeedItp)) {
                    continue;
                }
                // FIXME ERROR!! The original implementation, here and only the first non-blank pattern comparison, return the corresponding result!
                // FIXME ERROR!! Should be confirmed with Liang Fei!!
                String pattern = interpolate(patternNeedItp, interpolateParams);
                if (isMatchGlobPattern(pattern, value)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns the entries in the collection that match the Glob pattern.
     */
    public static Set<String> filterByGlobPattern(String pattern, Collection<String> values) {
        Set<String> ret = new HashSet<String>();
        if (pattern == null || values == null) {
            return ret;
        }

        for (String v : values) {
            if (isMatchGlobPattern(pattern, v)) {
                ret.add(v);
            }
        }
        return ret;
    }

    /**
     * Find the string that matches the Glob pattern. Multiple patterns, as long as a match pattern, it returns this string.
     */
    public static Set<String> filterByGlobPattern(Collection<String> patterns, Collection<String> values) {
        Set<String> ret = new HashSet<String>();
        if (null == patterns || values == null || patterns.isEmpty() || values.isEmpty()) {
            return ret;
        }

        for (String p : patterns) {
            for (String v : values) {
                if (isMatchGlobPattern(p, v)) {
                    ret.add(v);
                }
            }
        }
        return ret;
    }

    /**
     * Whether two Glob patterns have intersection.
     */
    public static boolean hasIntersection(String glob1, String glob2) {
        if (null == glob1 || null == glob2) {
            return false;
        }

        if (glob1.contains("*") && glob2.contains("*")) {
            int index1 = glob1.indexOf("*");
            int index2 = glob2.indexOf("*");

            String s11 = glob1.substring(0, index1);
            String s12 = glob1.substring(index1 + 1, glob1.length());

            String s21 = glob2.substring(0, index2);
            String s22 = glob2.substring(index2 + 1, glob2.length());

            if (!s11.startsWith(s21) && !s21.startsWith(s11)) return false;
            if (!s12.endsWith(s22) && !s22.endsWith(s12)) return false;
            return true;
        } else if (glob1.contains("*")) {
            return isMatchGlobPattern(glob1, glob2);
        } else if (glob2.contains("*")) {
            return isMatchGlobPattern(glob2, glob1);
        } else {
            return glob1.equals(glob2);
        }
    }

    /**
     * Parse Query String into Map. For strings that have only Key, key3 = </ code> is ignored.
     *
     * @param keyPrefix In the output of the Map Key plus a unified prefix.
     * @param query Query String，For example: <code>key1=value1&key2=value2</code>
     * @return When Query String is <code>key1=value1&key2=value2</code>, and prefix is <code>pre.</code>,
     *         then <code>Map{pre.key1=value1, pre.key=value2}</code> will be returned.
     */
    // FIXME Is it reasonable to throw an IllegalStateException??
    public static Map<String, String> parseQuery(String keyPrefix, String query) {
        if (query == null)
            return new HashMap<String, String>();
        if (keyPrefix == null)
            keyPrefix = "";

        Matcher matcher = QUERY_PATTERN.matcher(query);
        Map<String, String> routeQuery = new HashMap<String, String>();
        String key = null;
        while (matcher.find()) { // Match one by one
            String separator = matcher.group(1);
            String content = matcher.group(2);
            if (separator == null || separator.length() == 0
                    || "&".equals(separator)) {
                if (key != null)
                    throw new IllegalStateException("Illegal query string \""
                            + query + "\", The error char '" + separator
                            + "' at index " + matcher.start() + " before \""
                            + content + "\".");
                key = content;
            } else if ("=".equals(separator)) {
                if (key == null)
                    throw new IllegalStateException("Illegal query string \""
                            + query + "\", The error char '" + separator
                            + "' at index " + matcher.start() + " before \""
                            + content + "\".");
                routeQuery.put(keyPrefix + key, content);
                key = null;
            } else {
                if (key == null)
                    throw new IllegalStateException("Illegal query string \""
                            + query + "\", The error char '" + separator
                            + "' at index " + matcher.start() + " before \""
                            + content + "\".");
            }
        }
        /*if (key != null)
        throw new IllegalStateException("Illegal route rule \"" + query
                + "\", The error in the end char: " + key);*/
        return routeQuery;
    }

    public static Map<String, String> parseQuery(String query) {
        return parseQuery("", query);
    }

    /**
     * Replace the value of the url parameter.
     */
    public static String replaceParameter(String query, String key, String value) {
        if (query == null || query.length() == 0) {
            return key + "=" + value;
        }
        if (query.indexOf(key + "=") == -1) {
            return query + "&" + key + "=" + value;
        }
        Pattern pattern = REPLACE_PARAMETER_PATTERNS.get(key);
        if (pattern == null) {
            pattern = Pattern.compile(key.replaceAll("([^(_0-9A-Za-z)])", "\\\\$0") + "=[^&]+");
        }
        Matcher matcher = pattern.matcher(query);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, (key + "=" + value).replace("$", "\\$"));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static String appendParamToUri(String uri, String name, String value) {
        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(value)) return uri;
        if (uri.indexOf('?') != -1) {
            uri += "&" + name + "=" + value;
        } else {
            uri += "?" + name + "=" + value;
        }
        return uri;
    }

    public static String appendParamsToUri(String uri, Map<String, String> params) {
        StringBuilder buf = new StringBuilder(uri);
        boolean first = (uri.indexOf('?') < 0);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value))
                continue;
            if (first) {
                buf.append("?");
                first = false;
            } else {
                buf.append("&");
            }
            buf.append(key);
            buf.append("=");
            buf.append(value);
        }
        return buf.toString();
    }

    public static boolean matchEndStarPattern(String value, String pattern) {
        if (!pattern.endsWith("*")) throw new IllegalArgumentException("not end star pattern!");
        String perfix = pattern.substring(0, pattern.length() - 1);
        return value.startsWith(perfix);
    }
}
