/*******************************************************************************
 *  Copyright 2017 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 *  Licensed 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 cdac.medinfo.sdk.hl7282.baselibs.segmentfactory;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

import cdac.medinfo.sdk.hl7282.exceptions.InvalidDictionaryException;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.HL7Logger;
import cdac.medinfo.sdk.hl7282.utils.ISegmentMap;
import cdac.medinfo.sdk.hl7282.utils.ISegmentMapReader;

/**
 * SegmentMapReader provides implementation to ISegmentMapReader.
 * It uses ISegmentMap to represent segment structure.
 */
public final class SegmentMapReader implements ISegmentMapReader
{
	
	private final String strDataDictionaryPath = "SegmentMapDictionary.xml";
	private static SegmentMapReader objSegmentMapReader = null;
	private static Object mutex = new Object();

	private SegmentDictionary objSegmentDictionary = null;

	private URL urlResourceName = null;

	/**
	 * This constructor is used if user wants to inherit DictionaryReader and override populate method. 
	 */
	private SegmentMapReader() throws InvalidDictionaryException
	{
		urlResourceName = SegmentMapReader.class.getResource(strDataDictionaryPath);
		objSegmentDictionary = SegmentDictionary.createInstance();
	}

	/**
	 * Returns instance of Dictionary Reader if not created.
	 * @return - instance of DictionaryReader
	 */
	public static SegmentMapReader createInstance()throws InvalidDictionaryException
	{
		synchronized (mutex) 
		{
			if(objSegmentMapReader == null)
			{
				objSegmentMapReader = new SegmentMapReader();	
			}
		}
		return objSegmentMapReader;
	}

	/*
	 * Populates the Dictionary Data Provider with all the attributes from the Data Dictionary.
	 */
	private void populate(String strSegmentName) throws InvalidDictionaryException
	{
		try
		{
			URLConnection objJarURLConnection = urlResourceName.openConnection();

			SegmentXmlHandler objXmlHandler = new SegmentXmlHandler(objJarURLConnection.getInputStream());
			ISegmentMap objSegmentMap = new SegmentMap();

			if(objXmlHandler.populate(strSegmentName, objSegmentMap))
				objSegmentDictionary.addSegmentMap(strSegmentName, objSegmentMap);
		}
		catch(IOException ioe)
		{
			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger.getLogger().log(ioe.getMessage());
			}
			throw new InvalidDictionaryException(ioe);
		}
	}

	/**
	 * Retrieves SegmentMap for given name of segment.
	 * @param strSegmentName name of segment
	 * @return ISegmentMap - instance of SegmentMap 
	 */
	public ISegmentMap getSegmentMap(String strSegmentName)
	{
		strSegmentName = strSegmentName.substring(0, 3);
		if(!objSegmentDictionary.isSegmentPopulated(strSegmentName))
			populate(strSegmentName);

		return objSegmentDictionary.getSegmentMap(strSegmentName);
	}
}
