/**
 * 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.camel.component.properties;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import static java.lang.String.format;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A parser to parse a string which contains property placeholders
 */
public class DefaultPropertiesParser implements AugmentedPropertyNameAwarePropertiesParser {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public String parseUri(String text, Properties properties, String prefixToken, String suffixToken) throws IllegalArgumentException {
        return parseUri(text, properties, prefixToken, suffixToken, null, null, false);
    }

    public String parseUri(String text, Properties properties, String prefixToken, String suffixToken, String propertyPrefix, String propertySuffix,
                           boolean fallbackToUnaugmentedProperty) throws IllegalArgumentException {
        ParsingContext context = new ParsingContext(properties, prefixToken, suffixToken, propertyPrefix, propertySuffix, fallbackToUnaugmentedProperty);
        return context.parse(text);
    }

    public String parseProperty(String key, String value, Properties properties) {
        return value;
    }

    /**
     * This inner class helps replacing properties.
     */
    private final class ParsingContext {
        private final Properties properties;
        private final String prefixToken;
        private final String suffixToken;
        private final String propertyPrefix;
        private final String propertySuffix;
        private final boolean fallbackToUnaugmentedProperty;

        public ParsingContext(Properties properties, String prefixToken, String suffixToken, String propertyPrefix, String propertySuffix,
                              boolean fallbackToUnaugmentedProperty) {
            this.properties = properties;
            this.prefixToken = prefixToken;
            this.suffixToken = suffixToken;
            this.propertyPrefix = propertyPrefix;
            this.propertySuffix = propertySuffix;
            this.fallbackToUnaugmentedProperty = fallbackToUnaugmentedProperty;
        }

        /**
         * Parses the given input string and replaces all properties
         *
         * @param input Input string
         * @return Evaluated string
         */
        public String parse(String input) {
            return doParse(input, new HashSet<String>());
        }

        /**
         * Recursively parses the given input string and replaces all properties
         *
         * @param input                Input string
         * @param replacedPropertyKeys Already replaced property keys used for tracking circular references
         * @return Evaluated string
         */
        private String doParse(String input, Set<String> replacedPropertyKeys) {
            String answer = input;
            Property property;
            while ((property = readProperty(answer)) != null) {
                // Check for circular references
                if (replacedPropertyKeys.contains(property.getKey())) {
                    throw new IllegalArgumentException("Circular reference detected with key [" + property.getKey() + "] from text: " + input);
                }

                Set<String> newReplaced = new HashSet<String>(replacedPropertyKeys);
                newReplaced.add(property.getKey());

                String before = answer.substring(0, property.getBeginIndex());
                String after = answer.substring(property.getEndIndex());
                answer = before + doParse(property.getValue(), newReplaced) + after;
            }
            return answer;
        }

        /**
         * Finds a property in the given string. It returns {@code null} if there's no property defined.
         *
         * @param input Input string
         * @return A property in the given string or {@code null} if not found
         */
        private Property readProperty(String input) {
            // Find the index of the first valid suffix token
            int suffix = getSuffixIndex(input);

            // If not found, ensure that there is no valid prefix token in the string
            if (suffix == -1) {
                if (getMatchingPrefixIndex(input, input.length()) != -1) {
                    throw new IllegalArgumentException(format("Missing %s from the text: %s", suffixToken, input));
                }
                return null;
            }

            // Find the index of the prefix token that matches the suffix token
            int prefix = getMatchingPrefixIndex(input, suffix);
            if (prefix == -1) {
                throw new IllegalArgumentException(format("Missing %s from the text: %s", prefixToken, input));
            }

            String key = input.substring(prefix + prefixToken.length(), suffix);
            String value = getPropertyValue(key, input);
            return new Property(prefix, suffix + suffixToken.length(), key, value);
        }

        /**
         * Gets the first index of the suffix token that is not surrounded by quotes
         *
         * @param input Input string
         * @return First index of the suffix token that is not surrounded by quotes
         */
        private int getSuffixIndex(String input) {
            int index = -1;
            do {
                index = input.indexOf(suffixToken, index + 1);
            } while (index != -1 && isQuoted(input, index, suffixToken));
            return index;
        }

        /**
         * Gets the index of the prefix token that matches the suffix at the given index and that is not surrounded by quotes
         *
         * @param input       Input string
         * @param suffixIndex Index of the suffix token
         * @return Index of the prefix token that matches the suffix at the given index and that is not surrounded by quotes
         */
        private int getMatchingPrefixIndex(String input, int suffixIndex) {
            int index = suffixIndex;
            do {
                index = input.lastIndexOf(prefixToken, index - 1);
            } while (index != -1 && isQuoted(input, index, prefixToken));
            return index;
        }

        /**
         * Indicates whether or not the token at the given index is surrounded by single or double quotes
         *
         * @param input Input string
         * @param index Index of the token
         * @param token Token
         * @return {@code true}
         */
        private boolean isQuoted(String input, int index, String token) {
            int beforeIndex = index - 1;
            int afterIndex = index + token.length();
            if (beforeIndex >= 0 && afterIndex < input.length()) {
                char before = input.charAt(beforeIndex);
                char after = input.charAt(afterIndex);
                return (before == after) && (before == '\'' || before == '"');
            }
            return false;
        }

        /**
         * Gets the value of the property with given key
         *
         * @param key   Key of the property
         * @param input Input string (used for exception message if value not found)
         * @return Value of the property with the given key
         */
        private String getPropertyValue(String key, String input) {
            String augmentedKey = getAugmentedKey(key);
            boolean shouldFallback = fallbackToUnaugmentedProperty && !key.equals(augmentedKey);

            String value = doGetPropertyValue(augmentedKey);
            if (value == null && shouldFallback) {
                log.debug("Property with key [{}] not found, attempting with unaugmented key: {}", augmentedKey, key);
                value = doGetPropertyValue(key);
            }

            if (value == null) {
                StringBuilder esb = new StringBuilder();
                esb.append("Property with key [").append(augmentedKey).append("] ");
                if (shouldFallback) {
                    esb.append("(and original key [").append(key).append("]) ");
                }
                esb.append("not found in properties from text: ").append(input);
                throw new IllegalArgumentException(esb.toString());
            }

            return value;
        }

        /**
         * Gets the augmented key of the given base key
         *
         * @param key Base key
         * @return Augmented key
         */
        private String getAugmentedKey(String key) {
            String augmentedKey = key;
            if (propertyPrefix != null) {
                log.debug("Augmenting property key [{}] with prefix: {}", key, propertyPrefix);
                augmentedKey = propertyPrefix + augmentedKey;
            }
            if (propertySuffix != null) {
                log.debug("Augmenting property key [{}] with suffix: {}", key, propertySuffix);
                augmentedKey = augmentedKey + propertySuffix;
            }
            return augmentedKey;
        }

        /**
         * Gets the property with the given key, it returns {@code null} if the property is not found
         *
         * @param key Key of the property
         * @return Value of the property or {@code null} if not found
         */
        private String doGetPropertyValue(String key) {
            String value = System.getProperty(key);
            if (value != null) {
                log.debug("Found a JVM system property: {} with value: {} to be used.", key, value);
            } else if (properties != null) {
                value = properties.getProperty(key);
            }
            return parseProperty(key, value, properties);
        }
    }

    /**
     * This inner class is the definition of a property used in a string
     */
    private static final class Property {
        private final int beginIndex;
        private final int endIndex;
        private final String key;
        private final String value;

        private Property(int beginIndex, int endIndex, String key, String value) {
            this.beginIndex = beginIndex;
            this.endIndex = endIndex;
            this.key = key;
            this.value = value;
        }

        /**
         * Gets the begin index of the property (including the prefix token).
         */
        public int getBeginIndex() {
            return beginIndex;
        }

        /**
         * Gets the end index of the property (including the suffix token).
         */
        public int getEndIndex() {
            return endIndex;
        }

        /**
         * Gets the key of the property.
         */
        public String getKey() {
            return key;
        }

        /**
         * Gets the value of the property.
         */
        public String getValue() {
            return value;
        }
    }
}
