/*
 * 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.pirk.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Manages system properties. At first loading of this class, it will:
 * <p>
 * 1) Load in the DEFAULT_PROPERTY_FILE, if found on the classpath. (Currently 'pirk.properties')
 * <p>
 * 2) Load in any properties files in the LOCAL_PROPERTIES_DIR. The filenames must end with '.properties'
 * <p>
 * 3) Load in properties from the QUERIER_PROPERTIES_FILE and RESPONDER_PROPERTIES_FILE
 * 
 */
public class SystemConfiguration
{
	private static final Logger logger = LoggerFactory.getLogger(SystemConfiguration.class);

	private static final Properties props = new Properties();

	/**
	 * By default, these files should be found on the root of the classpath
	 */
	private static final String DEFAULT_PROPERTY_FILE = "pirk.properties";
	private static final String QUERIER_PROPERTIES_FILE = "querier.properties";
	private static final String RESPONDER_PROPERTIES_FILE = "responder.properties";

	private static final String LOCAL_PROPERTIES_DIR = "local.pirk.properties.dir";

	static
	{
		initialize();
	}

	public static void initialize()
	{
		props.clear();

		// First try to load the default properties file
		loadPropsFromResource(DEFAULT_PROPERTY_FILE);

		// Try to load props from the querier and responder property files, if they exist
		loadPropsFromResource(QUERIER_PROPERTIES_FILE);
		loadPropsFromResource(RESPONDER_PROPERTIES_FILE);

		// Try to load the local properties files, if they exists
		loadPropsFromDir(getProperty(LOCAL_PROPERTIES_DIR));
	}

	/**
	 * Gets the specified property; returns <code>null</code> if the property isn't found.
	 * 
	 * @param propertyName
	 *          The name of the requested property.
	 * @return The value of the property, or <code>null</code> if the property cannot be found.
	 */
	public static String getProperty(String propertyName)
	{
		return props.getProperty(propertyName);
	}

	/**
	 * Gets the specified property as a <code>String</code>, or the default value if the property isn't found.
	 * 
	 * @param propertyName
	 *          The name of the requested string property value.
	 * @param defaultValue
	 *          The value to return if the property is undefined.
	 * @return The value of the requested property, or the default value if the property is undefined.
	 */
	public static String getProperty(String propertyName, String defaultValue)
	{
		return props.getProperty(propertyName, defaultValue);
	}

	/**
	 * Gets the specified property as an <code>int</code>, or the default value if the property isn't found.
	 * 
	 * @param propertyName
	 *          The name of the requested int property value.
	 * @param defaultValue
	 *          The value to return if the property is undefined.
	 * @return The value of the requested property, or the default value if the property is undefined.
	 * @throws NumberFormatException
	 *           If the property does not contain a parsable <code>int</code> value.
	 */
	public static int getIntProperty(String propertyName, int defaultValue)
	{
		String value = props.getProperty(propertyName);
		return (value == null) ? defaultValue : Integer.parseInt(value);
	}

	/**
	 * Gets the specified property as an <code>long</code>, or the default value if the property isn't found.
	 * 
	 * @param propertyName
	 *          The name of the requested long property value.
	 * @param defaultValue
	 *          The value to return if the property is undefined.
	 * @return The value of the requested property, or the default value if the property is undefined.
	 * @throws NumberFormatException
	 *           If the property does not contain a parsable <code>long</code> value.
	 */
	public static long getLongProperty(String propertyName, long defaultValue)
	{
		String value = props.getProperty(propertyName);
		return (value == null) ? defaultValue : Long.parseLong(value);
	}

	/**
	 * Gets the specified property as a <code>boolean</code>, or the default value if the property isn't defined.
	 * 
	 * @param propertyName
	 *          The name of the requested boolean property value.
	 * @param defaultValue
	 *          The value to return if the property is undefined.
	 * @return <code>true</code> if the property is defined and has the value "true", otherwise <code>defaultValue</code>.
	 */
	public static boolean getBooleanProperty(String propertyName, boolean defaultValue)
	{
		return (isSetTrue(propertyName)) || defaultValue;
	}

	/**
	 * Returns <code>true</code> iff the specified boolean property value is "true".
	 * <p>
	 * If the property is not found, or it's value is not "true" then the method will return <code>false</code>.
	 * 
	 * @param propertyName
	 *          The name of the requested boolean property value.
	 * @return <code>true</code> if the property is defined and has the value "true", otherwise <code>false</code>.
	 */
	public static boolean isSetTrue(String propertyName)
	{
		String value = props.getProperty(propertyName);
		return "true".equals(value);
	}

	/**
	 * Sets the property to the given value.
	 * <p>
	 * Any previous values stored at the same property name are replaced.
	 * 
	 * @param propertyName
	 *          The name of the property to set.
	 * @param value
	 *          The property value.
	 */
	public static void setProperty(String propertyName, String value)
	{
		props.setProperty(propertyName, value);
	}

	/**
	 * Returns true iff the given property name is defined.
	 * 
	 * @param propertyName
	 *          The property name to test.
	 * @return <code>true</code> if the property is found in the configuration, or <code>false</code> otherwise.
	 */
	public static boolean hasProperty(String propertyName)
	{
		return props.containsKey(propertyName);
	}

	/**
	 * Appends a property via a comma separated list
	 * <p>
	 * If the property does not exist, it adds it.
	 * 
	 * @param propertyName
	 *          The property whose value is to be appended with the given value.
	 * @param value
	 *          The value to be stored, or appended to the current value.
	 */
	public static void appendProperty(String propertyName, String value)
	{
		String oldValue = props.getProperty(propertyName);

		if (oldValue != null && !oldValue.equals("none"))
		{
			oldValue += "," + value;
		}
		else
		{
			oldValue = value;
		}
		props.setProperty(propertyName, oldValue);
	}

	/**
	 * Loads the properties from local properties file in the specified directory.
	 * <p>
	 * All files ending in '.properties' will be loaded. The new properties are added to the current system configuration.
	 * 
	 * @param dirName
	 *          The directory to search for the new properties files.
	 */
	public static void loadPropsFromDir(String dirName)
	{
		logger.info("Loading properties from dirName = " + dirName);
		File[] directoryListing = new File(dirName).listFiles(new FilenameFilter()
		{
			@Override
			public boolean accept(File dir, String name)
			{
				return name.endsWith(".properties");
			}
		});

		if (directoryListing != null)
		{
			for (File file : directoryListing)
			{
				loadPropsFromFile(file);
			}
		}
	}

	/**
	 * Loads the properties from local properties file in the specified directory in hdfs.
	 * <p>
	 * All files ending in '.properties' will be loaded. The new properties are added to the current system configuration.
	 * 
	 * @param dirName
	 *          The directory to search for the new properties files.
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public static void loadPropsFromHDFSDir(String dirName, FileSystem fs) throws FileNotFoundException, IOException
	{
		logger.info("Loading properties from dirName = " + dirName);

		Path dirPath = new Path(dirName);

		FileStatus[] status = fs.listStatus(dirPath);
		for (int i=0;i<status.length;i++)
		{
			if(status[i].getPath().getName().endsWith(".properties"))
			{
				loadPropsFromFile(status[i].getPath(), fs);
			}
		}
	}

	/**
	 * Loads the properties from the specified file.
	 * <p>
	 * The new properties are added to the current system configuration.
	 * 
	 * @param file
	 *          The properties file containing the system properties to add.
	 */
	public static void loadPropsFromFile(File file)
	{
		if (file.exists())
		{
			try (InputStream stream = new FileInputStream(file))
			{
				logger.info("Loading properties file '" + file.getAbsolutePath() + "'");
				loadProperties(stream);
			} catch (IOException e)
			{
				logger.error("Problem loading properties file '" + file.getAbsolutePath() + "'");
				e.printStackTrace();
			}
		}
		else
		{
			logger.warn("Properties file does not exist: '" + file.getAbsolutePath() + "'");
		}
	}

	/**
	 * Loads the properties from the specified file in hdfs
	 * <p>
	 * The new properties are added to the current system configuration.
	 * 
	 * @param file
	 *          The properties file containing the system properties to add.
	 * @throws IOException 
	 */
	public static void loadPropsFromFile(String filename, FileSystem fs) throws IOException
	{
		Path p = new Path(filename);
		loadPropsFromFile(p, fs);
	}

	/**
	 * Loads the properties from the specified file in hdfs
	 * <p>
	 * The new properties are added to the current system configuration.
	 * 
	 * @param file
	 *          The properties file containing the system properties to add.
	 * @throws IOException 
	 */
	public static void loadPropsFromFile(Path filePath, FileSystem fs) throws IOException
	{
		if(fs.exists(filePath))
		{
			try (InputStream stream = fs.open(filePath);)
			{
				logger.info("Loading properties file from hdfs'" + filePath.toString() + "'");
				loadProperties(stream);
			} catch (IOException e)
			{
				logger.error("Problem loading properties file from hdfs '" + filePath.toString() + "'");
				e.printStackTrace();
			}
		}
		else
		{
			logger.warn("Properties file does not exist: '" + filePath.toString() + "'");
		}
	}

	/**
	 * Loads the properties from the specified resource on the current classloader.
	 * <p>
	 * The new properties are added to the current system configuration.
	 * 
	 * @param name
	 *          The name of the resource defining the properties.
	 */
	public static void loadPropsFromResource(String name)
	{
		try (InputStream stream = SystemConfiguration.class.getClassLoader().getResourceAsStream(name))
		{
			if (stream != null)
			{
				logger.info("Loading file '" + name + "'");
				loadProperties(stream);
			}
			else
			{
				logger.error("No file found '" + name + "'");
			}
		} catch (IOException e)
		{
			logger.error("Problem loading file '" + name + "'");
			e.printStackTrace();
		}
	}

	/**
	 * Load the properties in the Properties object and then trim any whitespace
	 * <p>
	 * Properties.load does not do this automatically
	 * @throws IOException 
	 */
	public static void loadProperties(InputStream stream) throws IOException
	{
		props.load(stream);

		Enumeration propKeys = props.propertyNames();
		while(propKeys.hasMoreElements()) 
		{
			String tmpKey = (String)propKeys.nextElement();
			String tmpValue = props.getProperty(tmpKey);
			tmpValue = tmpValue.trim();
			props.put(tmpKey, tmpValue);
		}
	}
}
