/*
 * Copyright (c) 2004-2017, by Alex Leigh.
 * All rights reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE
 * The copyright notice above does not evidence any
 * actual or intended publication of such source code.
 */

package lc.mecha.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;

public class PropertiesUtil {
    private static final Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);

    public static String requireProperty(Properties p, String key) {
        String value = p.getProperty(key);
        if (StringUtils.isEmpty(value)) throw new IllegalArgumentException("Property cannot be empty: " + key);
        return value;
    }

    /**
     * Given the properties <code>props</code> and the root <code>root</code>, remove any
     * keys matching root and strip root from the key path. Always returns a Properties
     * object, even if none were found.
     *
     * @param props
     * @param root
     * @return
     */
    public static Properties reduceProperties(final Properties props, final String root) {
        final Properties np = new Properties();

        assert (root.endsWith("."));

        for (final String key : props.stringPropertyNames()) {
            if (key.startsWith(root)) {
                // TODO: Assumes the dangling period, otherwise breaks
                final String newKey = key.substring(root.length() + 1, key.length());
                np.put(newKey, props.getProperty(key));
            }
        }

        return np;
    }

    /**
     * Attempt to load a properties file from the URL referenced in the VM environment
     * by the provided <code>envVariable</code> name. If the variable is not present
     * in the environment, <code>null</code> is returned.
     * <p>
     * If there is a problem parsing the URL, or fetching the file, an appropriate
     * <code>Exception</code> is thrown.
     *
     * @param envVariable
     * @return
     * @throws IOException
     */
    public static Properties loadRemoteConfigFromEnv(final String envVariable) throws IOException, URISyntaxException {
        final String urlStr = System.getenv(envVariable);
        if (urlStr == null) {
            return null;
        }
        return loadRemoteConfig(new URI(urlStr));
    }

    public static Properties loadProperties(final String filename) throws IOException {
        final Properties p = new Properties();
        p.load(Properties.class.getResourceAsStream(filename));
        return p;
    }

    /**
     * Attempt to load a properties file from the provided URL.
     * <p>
     * If there is a problem parsing the URL, or fetching the file, an appropriate
     * <code>Exception</code> is thrown.
     *
     * @param configUri
     * @return
     * @throws IOException
     */
    public static Properties loadRemoteConfig(final URI configUri) throws IOException {
        assert (configUri != null);

        logger.debug("Loading configuration from {}", configUri.toString());

        final Properties remoteProps = new Properties();

        if (configUri.getScheme().equals("file")) {
            logger.debug("Opening properties via FILE: {}", configUri.getPath());
            try (FileInputStream fis = new FileInputStream(configUri.getPath())) {
                remoteProps.load(fis);
            }

        } else {
            remoteProps.load(configUri.toURL().openStream());
        }

        logger.debug("Remote properties were: {}", remoteProps);

        return remoteProps;
    }
}
