package be.fgov.ehealth.technicalconnector.tests.utils;

/*
 * Copyright (c) eHealth
 */


import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

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

import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorExceptionValues;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;


/**
 * This class will load the testproperties files used in the unit tests.
 * 
 * @author EHD3
 * 
 */
public final class TestPropertiesLoader {

    private static final Logger LOG = LoggerFactory.getLogger(TestPropertiesLoader.class);

    private static Map<String, Properties> cache = new HashMap<String, Properties>();

    private static final String DEFAULT_PROP_NAME = "/be.ehealth.technicalconnector.test.properties";

    private TestPropertiesLoader() {
        super();
    }

    /**
     * @return the properties from default location
     * @throws TechnicalConnectorException
     */
    public static Properties getProperties() throws TechnicalConnectorException {
        return getProperties(DEFAULT_PROP_NAME);
    }

    public static Properties getProperties(String location) throws TechnicalConnectorException {
        return getProperties(location, SupportedLanguages.JAVA.getAbbreviation());
    }

    /**
     * @param location
     * @return the properties from given location
     * @throws TechnicalConnectorException
     */
    public static Properties getProperties(String location, String devLang) throws TechnicalConnectorException {
        LOG.debug("TestPropertiesLoader : loading properties from file " + location);
        if (!cache.containsKey(location)) {
            Properties props = new Properties();
            try {
                InputStream in = ConnectorIOUtils.getResourceAsStream(location, false);
                if (in == null) {
                    TechnicalConnectorExceptionValues errorValue = TechnicalConnectorExceptionValues.ERROR_CONFIG;
                    throw new TechnicalConnectorException(errorValue, "Could not load test properties file [" + location + "]");
                }
                props.load(in);
            } catch (IOException e) {
                TechnicalConnectorExceptionValues errorValue = TechnicalConnectorExceptionValues.ERROR_CONFIG;
                throw new TechnicalConnectorException(errorValue, "Could not load test properties file");
            }
            cache.put(location, processProps(props, devLang));

        }

        return (Properties) cache.get(location)
                                 .clone();
    }

    public static Properties processProps(Properties props, String devLang) {
        Properties solvedProps = new Properties();
        for (Object key : props.keySet()) {
            String value = getValue(props, key.toString(), null);
            if (SupportedLanguages.NET.getAbbreviation()
                                      .equals(devLang)) {
                if (value.startsWith("/")) {
                    value = StringUtils.replaceOnce(value, "/", ".\\\\");
                    LOG.info("Replacing [" + key + "] with value [" + value + "]");
                }
            }
            if (value != null) {
                solvedProps.put(key, value);
            } else {
                throw new IllegalStateException("TestPropertiesLoader : no value defined for property " + key + " ,fill this property, or remove it if not needed ");
            }
        }
        return solvedProps;
    }

    private static String getValue(Properties props, String key, String defaultValue) {
        String keyValue = key;
        if (props.getProperty(key) != null && props.getProperty(key)
                                                   .startsWith("${")) {
            keyValue = StringUtils.substringBetween(props.getProperty(key), "${", "}");
            return getValue(props, keyValue, defaultValue);
        }
        return props.getProperty(key, defaultValue);
    }

}
