/**
 *
 */
package org.jboss.resteasy.util;

import java.util.regex.Pattern;

/**
 * A utility class for handling URI template parameters. As the Java
 * regulare expressions package does not handle named groups, this
 * class attempts to simulate that functionality by using groups.
 *
 * @author Ryan J. McDonough
 * @author Bill Burke
 * @since 1.0
 *        Nov 8, 2006
 */
public class PathHelper {
    public static final String URI_PARAM_NAME_REGEX = "\\w[\\w\\.-]*";
    public static final String URI_PARAM_REGEX_REGEX = "[^{}][^{}]*";
    public static final String URI_PARAM_REGEX = "\\{\\s*(" + URI_PARAM_NAME_REGEX + ")\\s*(:\\s*(" + URI_PARAM_REGEX_REGEX
            + "))?\\}";
    public static final String URI_PARAM_WITH_REGEX = "\\{\\s*(" + URI_PARAM_NAME_REGEX + ")\\s*(:\\s*(" + URI_PARAM_REGEX_REGEX
            + "))\\}";
    public static final String URI_PARAM_WITHOUT_REGEX = "\\{(" + URI_PARAM_NAME_REGEX + ")\\}";
    public static final Pattern URI_PARAM_PATTERN = Pattern.compile(URI_PARAM_REGEX);
    public static final Pattern URI_PARAM_WITH_REGEX_PATTERN = Pattern.compile(URI_PARAM_WITH_REGEX);
    public static final Pattern URI_PARAM_WITHOUT_REGEX_PATTERN = Pattern.compile(URI_PARAM_WITHOUT_REGEX);

    /**
     * A regex pattern that searches for a URI template parameter in the form of {*}
     */
    public static final Pattern URI_TEMPLATE_PATTERN = Pattern.compile("(\\{([^}]+)\\})");

    public static final String URI_TEMPLATE_REPLACE_PATTERN = "(.*?)";

    public static String getEncodedPathInfo(String path, String contextPath) {
        if (contextPath != null && !"".equals(contextPath) && path.startsWith(contextPath)) {
            path = path.substring(contextPath.length());
        }
        return path;

    }

    public static final char openCurlyReplacement = 6;
    public static final char closeCurlyReplacement = 7;

    public static String replaceEnclosedCurlyBraces(String str) {
        char[] chars = str.toCharArray();
        int open = 0;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '{') {
                if (open != 0)
                    chars[i] = openCurlyReplacement;
                open++;
            } else if (chars[i] == '}') {
                open--;
                if (open != 0) {
                    chars[i] = closeCurlyReplacement;
                }
            }
        }
        return new String(chars);
    }

    /**
     * A cheaper (memory-wise) version of replaceEnclosedCurlyBraces(String str).
     *
     * @param str input string
     * @return replaced output
     */
    public static CharSequence replaceEnclosedCurlyBracesCS(String str) {
        int open = 0;
        CharSequence cs = str;
        char[] chars = null;
        for (int i = 0; i < str.length(); i++) {
            if (cs.charAt(i) == '{') {
                if (open != 0) {
                    if (cs == str) {
                        chars = str.toCharArray();
                        cs = new ArrayCharSequence(chars);
                    }
                    chars[i] = openCurlyReplacement;
                }
                open++;
            } else if (cs.charAt(i) == '}') {
                open--;
                if (open != 0) {
                    if (cs == str) {
                        chars = str.toCharArray();
                        cs = new ArrayCharSequence(chars);
                    }
                    chars[i] = closeCurlyReplacement;
                }
            }
        }
        return cs;
    }

    public static String recoverEnclosedCurlyBraces(String str) {
        return str.replace(openCurlyReplacement, '{').replace(closeCurlyReplacement, '}');
    }

}
