/*
 * 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.openjpa.lib.util;

/**
 * Allows for simple regex style testing of strings. The wildcard '.'
 * is used to represent any single character, while '.*' is used to represent
 * any series of 0 or more characters. Examples:<br />
 * <code> SimpleRegex re = new SimpleRegex("the qu.ck .* dog", true);
 * boolean matches = re.matches("The quick fox jumped over the lazy dog");
 * </code>
 *
 */
public class SimpleRegex {

    private final String expr;
    private final boolean caseInsensitive;

    public SimpleRegex(String expr, boolean caseInsensitive) {
        this.caseInsensitive = caseInsensitive;

        // If we're case insensitive, toLowerCase the expr.  We'll toLowerCase
        // each target, too, in the matches call.
        if (caseInsensitive)
            this.expr = expr.toLowerCase();
        else
            this.expr = expr;
    }

    public boolean matches(String target) {
        // If we're case insensitive, toLowerCase the target
        if (caseInsensitive)
            target = target.toLowerCase();

        // By default, we are not position independent("mobile"). We only
        // become position independent once we hit our first ".*".
        boolean mobile = false;

        // Find occurrences of ".*" in the expression.
        int exprPos = 0;
        int targetPos = 0;
        while (true) {
            // Find the next occurrence of ".*"
            int star = expr.indexOf(".*", exprPos);

            // If we're at a ".*" now, simply skip it and become position
            // independent
            if (star == exprPos) {
                mobile = true;
                exprPos += 2;
                continue;
            }
            // If there are no more ".*"s, then we're effectively no longer
            // position independent(assuming we even were before), since
            // we must match the end of the string
            else if (star == -1) {
                int len = expr.length() - exprPos;

                // If we're not mobile, then the remainder of the expr and
                // target must be the same length.  If not, then it's not a
                // match.  If we're mobile, then the length doesn't have to
                // be the same as long as the remainder of the expression
                // is equal to the end of the target
                if (!mobile && targetPos != target.length() - len)
                    return false;

                // In anycase, the remaining length of the target must be
                // at least as long as the remaining length of the expression.
                // (We check now to avoid sending a negative start pos to
                // indexOf)
                if (target.length() < len)
                    return false;

                // Match the end of the target to the remainder of the
                // expression
                int match = indexOf(target, target.length() - len, exprPos,
                    len, true);
                if (match != -1)
                    return true;
                return false;
            }

            // Match the fragment of the expression to the target
            int match = indexOf(target, targetPos, exprPos,
                star - exprPos, !mobile);
            if (match == -1)
                return false;
            targetPos = match + star - exprPos;
            exprPos = star + 2;
            mobile = true;
        }
    }

    /**
     * Match a section of target to a fragment of the expression.
     * If we're only to match the beginning of the target, beginOnly
     * will be true, otherwise we can match anymore in the target(starting
     * at the targetStart position). A "." in the expression matches any
     * character.
     */
    private int indexOf(String target, int targetStart,
        int exprStart, int exprLength, boolean beginOnly) {
        // Run through the target seeing if there is a match
        while (target.length() - targetStart >= exprLength) {
            // Assume success.  If there isn't a match we'll break out
            boolean found = true;
            for (int i = 0; i < exprLength; i++) {
                // "." in the expr matches any character in the target
                if (expr.charAt(exprStart + i) != '.' &&
                    expr.charAt(exprStart + i) !=
                        target.charAt(targetStart + i)) {
                    found = false;
                    break;
                }
            }
            if (found)
                return targetStart;

            // If we're position dependent(beginOnly == true), then don't
            // continue the search
            if (beginOnly)
                return -1;

            targetStart++;
        }
        return -1;
    }
}
