/*******************************************************************************
 *  Copyright 2017-2018 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.dcm30_04.services.dicomdir;

import java.io.IOException;
import java.util.Locale;


import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidDataElementException;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.DICOMDIRException;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.EnumImplOpsStatus;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.SourceException;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.DicomMessage;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.IDataSource;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.IQueryModel;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;
import cdac.medinfo.sdk.dcm30_04.utils.EnumFeatureList;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.ResourceBundleWrapper;

/**
 * This class provides a default implementation of Data Source which will search and retrieve data from DICOMDIR . 
 * It works as a source to query and retrieve the data from the DICOMDIR File.    
 */
public class DICOMDIRSourceImpl implements IDataSource 
{
	/*
	 * Path of Directory of DICOMDIR.
	 */
	private String strDICOMDIRPath ;

	/**
	 * Instantiates DICOMDIR Source Implementation.
	 * @param strDICOMDIRPath String value of path of DICOMDIR.
	 */
	public DICOMDIRSourceImpl(String strDICOMDIRPath)
	{
		this.strDICOMDIRPath = strDICOMDIRPath;
	}

	/**
	 * This method finds the value of given data elements in the Dataset according to the match of key value.
	 * @param objIDataSet instance of DataSet containing key value and other data elements that are to be retrieved.
	 * @param objRSTDataSetCollection DataSet collection containing the matches.
	 * @return short - shows status value which will be used in generation of response
	 * 					Refer EnumImplOpsStatus for supported response status values.
	 * @throws SourceException throws {@link SourceException} if find fails.
	 */
	public short find(DicomMessage objDicomMessage , ISingleCollection<IDataSet> objRSTDataSetCollection)
	{
		try
		{
			/*
			 * Create instance of DICOMDIR.
			 */
			IDataSet objIDataSet = objDicomMessage.getDataSet();
			DICOMDIR objDicomdir = new DICOMDIR(strDICOMDIRPath);
			if(!objDicomdir.find(objIDataSet, objRSTDataSetCollection))
				return EnumImplOpsStatus.FAILURE.getValue();
		}
		catch(DICOMDIRException de)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(de.getMessage());
			}
			throw new SourceException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.SourceException", new Locale(DicomConfig.createInstance().getLocale())),de);
		}
		catch(IOException ioe)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ioe.getMessage());
			}
			throw new SourceException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.SourceException", new Locale(DicomConfig.createInstance().getLocale())),ioe);
		}
		catch (InvalidDataElementException ide)
		{
			if (DicomConfig.createInstance().isLoggingOn())
			{
			    DicomLogger objDicomLogger = DicomLogger.getLogger();
			    objDicomLogger.log(ide.getMessage());
			}
			return EnumImplOpsStatus.FAILURE.getValue();
		}
		return EnumImplOpsStatus.SUCCESS.getValue();
	}

	/**
	 * This method finds the data set in the DICOMDIR according to key value.
	 * Retrieves the Dicom Files in which the key value is present.
	 * @param objIDataSet instance of dataset containing key value.
	 * @param objRstDataCollection data set collection containing all matched data set.
	 * @return short - shows status value which will be used in generation of response
	 * 					Refer EnumImplOpsStatus for supported response status values.
	 * @throws SourceException throws {@link SourceException} if retrieve fails.
	 */
	public short retrieve(DicomMessage objDicomMessage, ISingleCollection<IDataSet> objRstDataCollection)
	{
		try
		{
			IDataSet objIDataSet = objDicomMessage.getDataSet();
			DICOMDIR objDICOMDIR = new DICOMDIR(strDICOMDIRPath);
			if(!objDICOMDIR.retrieve(objIDataSet, objRstDataCollection))
				return EnumImplOpsStatus.FAILURE.getValue();
		}
		catch(DICOMDIRException de)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(de.getMessage());
			}
			throw new SourceException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.SourceException", new Locale(DicomConfig.createInstance().getLocale())),de);
		}
		catch(IOException ioe)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ioe.getMessage());
			}
			throw new SourceException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.SourceException", new Locale(DicomConfig.createInstance().getLocale())),ioe);
		}
		catch (InvalidDataElementException ide)
		{
			if (DicomConfig.createInstance().isLoggingOn())
			{
			    DicomLogger objDicomLogger = DicomLogger.getLogger();
			    objDicomLogger.log(ide.getMessage());
			}
			return EnumImplOpsStatus.FAILURE.getValue();
		}
		return EnumImplOpsStatus.SUCCESS.getValue();
	}

	/**
	 * Depending on the keys in the DCMQuery model it finds the matching DataSets and returns status.
	 * According to the matched sets populates the collection of DCMResultSet taken as out parameter.
	 * @param objRstQueryModel the resultant query model containing the matched attributes.
	 * @param objQueryModel the object query model
	 * @return short - shows status value which will be used in generation of response
	 * 					Refer EnumImplOpsStatus for supported response status values.
	 */
	public short find(IQueryModel objQueryModel, IQueryModel objRstQueryModel)
	{
		return EnumImplOpsStatus.FAILURE.getValue();
	}

	@Override
	public short retrieve(IQueryModel arg0, IQueryModel arg1)
	{
		return EnumImplOpsStatus.FAILURE.getValue();
	}

}
