package gov.va.med.fw.ui.struts;

// Java imports
import gov.va.med.fw.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.ArrayList;
import java.util.List;
import java.net.URL;

// CSX imports
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.PropertyMessageResources;

/**
 * This method does exactly what its parent is doing except that it reads multiple files(CSV)for 
 * each resource bundle instead of one file.
 *
 * @author Muddaiah Ranga
 * @version 3.0
 */
public class CustomPropertyMessageResources extends PropertyMessageResources 
{
	/**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = -8550266508694280857L;

	/**
	 * Construct a new PropertyMessageResources according to the
	 * specified parameters.
	 *
	 * @param factory The MessageResourcesFactory that created us
	 * @param config The configuration parameter for this MessageResources
	 */
	public CustomPropertyMessageResources(MessageResourcesFactory pFactory,String pConfig)
	{
		super(pFactory, pConfig);
	}

	public CustomPropertyMessageResources(MessageResourcesFactory pFactory,String pConfig,boolean pReturnNull)
	{
		super(pFactory, pConfig, pReturnNull);
	}


	/**
	 * This method does exactly what its parent is doing except that it takes CSV string for 
	 * each resource bundle instead of one file.
	 *
	 * @param localeKey Locale key for the messages to be retrieved
	 */
	protected synchronized void loadLocale(String localeKey) 
	{
		if (log.isTraceEnabled())
		{
			log.trace("loadLocale(" + localeKey + ")");
		}

		// Have we already attempted to load messages for this locale?
		if (locales.get(localeKey) != null)
		{
			return;
		}
		locales.put(localeKey, localeKey);

		// Set up to load the property resource for this locale key, if we can
		String name = config.replace('.', '/');

		// break down the 'long' String for .properties if there are more than one listed in <message-resources>
		List propertyList = getMessageBundles(name);

		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		if (classLoader == null)
		{
			classLoader = this.getClass().getClassLoader();
		}

		for (int k=0; k < propertyList.size(); k++)
		{
			name = (String) propertyList.get(k);
			if (localeKey.length() > 0)
			{
				name += "_" + localeKey;
			}
			name += ".properties";			
			if (log.isTraceEnabled()) 
			{
				log.trace("  Loading resource '" + name + "'");
			}
			
			InputStream is = null;
			Properties props = new Properties();
			
			// Load the specified property resource
			is = classLoader.getResourceAsStream(name);
			if(is != null)
			{
				URL resourceURL = classLoader.getResource(name);

				log.info("\n");
				log.info("Reading resource " + resourceURL );

				try
				{
					props.load(is);
				}
				catch (IOException ex)
				{
					log.error("loadLocale()", ex);
				}
				finally
				{
					try
					{
						is.close();
					}
					catch (IOException ex)
					{
						log.error("loadLocale()", ex);
					}
				}
			}

			if (log.isTraceEnabled()) 
			{
				log.trace("  Loading resource completed");
			}

			// Copy the corresponding values into our cache
			if (props.size() < 1) 
			{
				continue;  // continue with the next property file
			}

			synchronized (messages)
			{
				Iterator names = props.keySet().iterator();
				while (names.hasNext())
				{
					final String key = (String) names.next();
					final String value = props.getProperty(key);

					final String localeMessageKey = messageKey(localeKey, key);
					final String existingMessage = (String) messages.get(localeMessageKey);

					if (existingMessage != null)
					{
						// the following were added for tracking/debugging purpose .. please don't delete them.
						log.info("\n");
						log.info("WARNING Duplicate Struts Message Properties Key detected while loading " + name);
						log.info("Key           = " + key);
						log.info("Previous Value= " + existingMessage);
						log.info("New Value     = " + value);
						final boolean isEqual = existingMessage.equals(value);
						if (isEqual)
						{
						    log.info("Previous Value is equal to the New Value.");
						}
						else
						{
						    log.info("Previous Value is NOT equal to the New Value.");
						}

                        if (log.isTraceEnabled())
						if (log.isTraceEnabled())
						{
							log.trace("  Override message key '" + localeMessageKey + "' with [" + value + "] Previously it was [" + existingMessage + "] " + (isEqual ? "EQUAL" : "NOT EQUAL"));
						}
					}
					else
					{
						if (log.isTraceEnabled())
						{
							log.trace("  Saving message key '" + localeMessageKey);
						}
					}

					messages.put(localeMessageKey, value);
				}
			}
		}
	}

	/**
	 * Splits the CSV in to seperated strings.
	 * 
	 * @param nameString the CSV string
	 * @return list of strings
	 */
	private List getMessageBundles(String nameString)
	{
		List messageBundlesList = new ArrayList();

		if (nameString != null)
		{
			String names[] = nameString.split(",");
			if(names != null)
			{
				for(int i=0; i<names.length; i++)
				{
					String name = names[i].trim();
					if(StringUtils.isNotEmpty(name))
					{
						messageBundlesList.add(name);
					}
				}
			}
		}
		return messageBundlesList;
   }
}
