
/*
 *  Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
*/
package oracle.sample;

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

/**
 * <p>
 * </p>
 *
 * @author velsubra
 */
public class PropertyTypeResolver implements IPropertyFinder {

    Properties currentlyResolved = null;
    protected String optionalPrefix = null;

    public String resolveAs(String var, String asProp) {
        if (var == null) return "${" + asProp + "}";
        String ret = replace(var, this, false);
        if (ret == null) {
            ret = "";
        }
        if (asProp != null) {
            currentlyResolved.put(asProp, ret);
        }
        return ret;
    }

    public PropertyTypeResolver(Properties known, String optionalPrefix) {
        if (known == null) {
            known = new Properties();
        }
        this.optionalPrefix = optionalPrefix;
        this.currentlyResolved = known;
    }

    public void addProperties(Properties props) {
        for (Object key :  props.keySet()) {
            currentlyResolved.setProperty(key.toString(), props.getProperty(key.toString()));
        }
    }

    @Override
    public String findProperty(String name) {
        String ret = (String) currentlyResolved.get(name);
        if (ret == null ) {
            if (optionalPrefix != null) {
                if (name.startsWith(optionalPrefix))  {
                    ret = findProperty(name.substring(optionalPrefix.length(), name.length()));
                }
            }
        }
        return ret;
    }

    public static String replace(String origString, IPropertyFinder keys, boolean exceptionWhenNotAllResolved) {
        if (keys == null || origString == null) return origString;
        StringBuffer finalString = new StringBuffer();
        int index = 0;
        int i = 0;
        String key = null;
        // CheckStyle:MagicNumber OFF
        while ((index = origString.indexOf("${", i)) > -1) {
            int endIndex = origString.indexOf("}", index + 3);
            if (endIndex < 0) {
                throw new RuntimeException("Matching } could not be found at:" +
                        origString);
            }
            key = origString.substring(index + 2, endIndex);
            finalString.append(origString.substring(i, index));
            String val = keys.findProperty(key);
            if (val != null) {
                finalString.append(val);
            } else {

                if (exceptionWhenNotAllResolved) {
                    throw new RuntimeException("Variable ${" + key + "} could not be resolved.");
                }
                finalString.append("\\$\\{");
                finalString.append(key);
                finalString.append("\\}");
            }
            i = index + 3 + key.length();
        }

        finalString.append(origString.substring(i));
        return finalString.toString();
    }
}