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

import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import freemarker.cache.MruCacheStorage;
import freemarker.log.Logger;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.StringUtil;

/**
 * Helper for language features (like built-ins) that use regular expressions. 
 */
final class RegexpHelper {

    private static final Logger LOG = Logger.getLogger("freemarker.runtime");
    
    private static volatile boolean flagWarningsEnabled = LOG.isWarnEnabled();
    private static final int MAX_FLAG_WARNINGS_LOGGED = 25;
    private static final Object flagWarningsCntSync = new Object();
    private static int flagWarningsCnt;
    
    private static final MruCacheStorage patternCache = new MruCacheStorage(50, 150);

    static private long intFlagToLong(int flag) {
        return flag & 0x0000FFFFL;
    }

    // Standard regular expression flags converted to long:
    static final long RE_FLAG_CASE_INSENSITIVE = intFlagToLong(Pattern.CASE_INSENSITIVE);

    static final long RE_FLAG_MULTILINE = intFlagToLong(Pattern.MULTILINE);

    static final long RE_FLAG_COMMENTS = intFlagToLong(Pattern.COMMENTS);

    static final long RE_FLAG_DOTALL = intFlagToLong(Pattern.DOTALL);

    // FreeMarker-specific regular expression flags (using the higher 32 bits):
    static final long RE_FLAG_REGEXP = 0x100000000L;

    static final long RE_FLAG_FIRST_ONLY = 0x200000000L;
    
    // Can't be instantiated
    private RegexpHelper() { }

    static Pattern getPattern(String patternString, int flags)
    throws TemplateModelException {
        PatternCacheKey patternKey = new PatternCacheKey(patternString, flags);
        
        Pattern result;
        
        synchronized (patternCache) {
            result = (Pattern) patternCache.get(patternKey);
        }
        if (result != null) {
            return result;
        }
        
        try {
            result = Pattern.compile(patternString, flags);
        } catch (PatternSyntaxException e) {
            throw new _TemplateModelException(e,
                    "Malformed regular expression: ", new _DelayedGetMessage(e));
        }
        synchronized (patternCache) {
            patternCache.put(patternKey, result);
        }
        return result;
    };

    private static class PatternCacheKey {
        private final String patternString;
        private final int flags;
        private final int hashCode;
        
        public PatternCacheKey(String patternString, int flags) {
            this.patternString = patternString;
            this.flags = flags;
            hashCode = patternString.hashCode() + 31 * flags;
        }
        
        @Override
        public boolean equals(Object that) {
            if (that instanceof PatternCacheKey) {
                PatternCacheKey thatPCK = (PatternCacheKey) that; 
                return thatPCK.flags == flags
                        && thatPCK.patternString.equals(patternString);
            } else {
                return false;
            }
        }

        @Override
        public int hashCode() {
            return hashCode;
        }
        
    }

    static long parseFlagString(String flagString) {
        long flags = 0;
        for (int i = 0; i < flagString.length(); i++) {
            char c = flagString.charAt(i);
            switch (c) {
                case 'i':
                    flags |= RE_FLAG_CASE_INSENSITIVE;
                    break;
                case 'm':
                    flags |= RE_FLAG_MULTILINE;
                    break;
                case 'c':
                    flags |= RE_FLAG_COMMENTS;
                    break;
                case 's':
                    flags |= RE_FLAG_DOTALL;
                    break;
                case 'r':
                    flags |= RE_FLAG_REGEXP;
                    break;
                case 'f':
                    flags |= RE_FLAG_FIRST_ONLY;
                    break;
                default:
                    if (flagWarningsEnabled) {
                        RegexpHelper.logFlagWarning(
                                "Unrecognized regular expression flag: "
                                + StringUtil.jQuote(String.valueOf(c)) + ".");
                    }
            }  // switch
        }
        return flags;
    }

    /**
     * Logs flag warning for a limited number of times. This is used to prevent
     * log flooding.
     */
    static void logFlagWarning(String message) {
        if (!flagWarningsEnabled) return;
        
        int cnt;
        synchronized (flagWarningsCntSync) {
            cnt = flagWarningsCnt;
            if (cnt < MAX_FLAG_WARNINGS_LOGGED) {
                flagWarningsCnt++;
            } else {
                flagWarningsEnabled = false;
                return;
            }
        }
        message += " This will be an error in some later FreeMarker version!";
        if (cnt + 1 == MAX_FLAG_WARNINGS_LOGGED) {
            message += " [Will not log more regular expression flag problems until restart!]";
        }
        LOG.warn(message);
    }

    static void checkNonRegexpFlags(String biName, long flags) throws _TemplateModelException {
        checkOnlyHasNonRegexpFlags(biName, flags, false);
    }
    
    static void checkOnlyHasNonRegexpFlags(String biName, long flags, boolean strict)
            throws _TemplateModelException {
        if (!strict && !flagWarningsEnabled) return;
        
        String flag; 
        if ((flags & RE_FLAG_MULTILINE) != 0) {
            flag = "m";
        } else if ((flags & RE_FLAG_DOTALL) != 0) {
            flag = "s";
        } else if ((flags & RE_FLAG_COMMENTS) != 0) {
            flag = "c";
        } else {
            return;
        }

        final Object[] msg = { "?", biName ," doesn't support the \"", flag, "\" flag "
                + "without the \"r\" flag." };
        if (strict) {
            throw new _TemplateModelException(msg);
        } else {
            // Suppress error for backward compatibility
            logFlagWarning(new _ErrorDescriptionBuilder(msg).toString());
        }
    }
    
}
