package com.javahonk;

import java.io.File;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xpath.CachedXPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class XMLConfig
{
   private static final String ENVIRONMENT = "DEV";
   private static final Node CONFIG_ROOT;
   private static final CachedXPathAPI XPATH_API;
   private static final HashMap<String, String> CONFIG_CACHE = new HashMap<String, String>();

   static
   {
      //static initializer
      try
      {
         File oConfigFile = new File("src\\main\\resources\\XMLBootstrap.xml");
         DocumentBuilderFactory oFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder oBuilder = oFactory.newDocumentBuilder();
         Document oDoc = oBuilder.parse(oConfigFile);
         XPATH_API = new CachedXPathAPI();
         CONFIG_ROOT = XPATH_API.selectSingleNode(oDoc, "/SAMPLE_CONFIG/" + ENVIRONMENT);
         if (CONFIG_ROOT == null)
         {
            throw new Exception("Unable to location environment configuration at '/SAMPLE_CONFIG/" + ENVIRONMENT + "'.");
         }
      }
      catch (Exception e)
      {
         throw new RuntimeException("Unable to load trexo bootstrap file at XMLBootstrap.xml.", e);
      }
   }
   
   //returns a bootstrap parameter as a string
   public static String GetString(String sParamName)
   {
      //first check the cache
      String sReturn = (String) CONFIG_CACHE.get(sParamName);

      if (sReturn == null)
      {
         //not in cache so retrieve it from the XML then put it in the cache
         sReturn = GetParameterAsString(sParamName);
         CONFIG_CACHE.put(sParamName, sReturn);
      }

      return sReturn;
   }
   
   public static int GetInt(String sParamName)
   {
      return Integer.parseInt(GetString(sParamName));
   }

   public static boolean GetBool(String sParamName)
   {
      return Boolean.getBoolean(GetString(sParamName));
   }

   //it is assumed that the name of the node is the parameter name and
   //the value of the text node is the value of the parameter
   private static String GetParameterAsString(String sParamName)
   {
      try
      {
         Node oNode = null;

         synchronized(XPATH_API)
         {
            //synchronize access to the XPath evaluation object
            oNode = XPATH_API.selectSingleNode(CONFIG_ROOT, sParamName + "/text()");
         }

         if (oNode == null)
         {
            //if null, then the parameter isn't defined so throw an exception
            throw new RuntimeException("Unable to locate parameter '" + sParamName + "' in the " + ENVIRONMENT + " region of the bootstrap configuration file.");
         }
         
         return oNode.getNodeValue();
      }
      catch (Exception e)
      {
         //if the XPath fails, then the TransformerException will be caught here
         throw new RuntimeException("Unable to locate parameter '" + sParamName + "' in the " + ENVIRONMENT + " region of the bootstrap configuration file.");
      }
   }
}