/*******************************************************************************
 *  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.File;
import java.io.IOException;
import java.util.Locale;


import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
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.SinkException;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.DicomMessage;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.IDataSink;
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.ResourceBundleWrapper;

/**
 * This class provides a default implementation of DataSink to store the data in DICOMDIR .
 * It serializes the data at the specified location and also populates DICOMDIR 
 * which can be used further if same SCP works for query and retrieval.
 * This class implements interface IDICOMDIRPathFormatter , to format long file names to short form.
 * Here in the default implementation the folder structure at the Patient, Study and Series level is created by 
 * the last eight characters of PatientName_PatientID, Study Instance UID, Series Instance UID. The File is saved with the 
 * last eight characters of SOP Instance UID.
 * This class should be set as Path Formatter in DICOMDIR class. When DataSet is stored in DICOMDIR then
 * formatPath(String strLongFileName) method is called with the long file name and formated path is returned.
 * The file in DICOMDIR is stored with the file name returned from above function.
 */
public class DICOMDIRSinkImpl implements IDataSink , IDICOMDIRPathFormatter
{

	/**
	 * This function stores the DataSet at the specified location and also make entry of file in DIOCMDIR file.
	 * This class implements interface IDICOMDIRPathFormatter , to format long file names to short form.
	 * Here in the default implementation the folder structure at the Patient, Study and Series level is created by 
	 * the last eight characters of PatientName_PatientID, Study Instance UID, Series Instance UID. 
	 * The Dicom File is saved with the last eight characters of SOP Instance UID.
	 * @param objDicomMessage DicomMessage containing DataSet to be stored in DICOMDIR and to be written in file at path speciifed.
	 * @param strStoragePath Storage path where the file to be stored
	 * @return short - shows status value which will be used in generation of response
	 * 					Refer EnumImplOpsStatus for supported response status values.
	 */
	public short store(DicomMessage objDicomMessage, String strStoragePath)
	{
		try
		{
			IDataSet objIDataSet = objDicomMessage.getDataSet();
			if(store(objIDataSet,strStoragePath))
				return EnumImplOpsStatus.SUCCESS.getValue();
		}
		catch(IOException ioe)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ioe.getMessage());
			}
			throw new SinkException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.StorageException", new Locale(DicomConfig.createInstance().getLocale())),ioe);
		}
		return EnumImplOpsStatus.FAILURE.getValue();
	}

	/**
	 * This function stores the DataSet at the specified location and also make entry of file in DIOCMDIR file.
	 * This class implements interface IDICOMDIRPathFormatter , to format long file names to short form.
	 * Here in the default implementation the folder structure at the Patient, Study and Series level is created by 
	 * the last eight characters of PatientName_PatientID, Study Instance UID, Series Instance UID. 
	 * The Dicom File is saved with the last eight characters of SOP Instance UID.
	 * @param objDicomMessage DicomMessage containing DataSet to be stored in DICOMDIR and to be written in file at path speciifed.
	 * @param strStoragePath Storage path where the file to be stored
	 * @return short - shows status value which will be used in generation of response
	 */
	public boolean store(IDataSet objIDataSet, String strStoragePath)
	{
		try
		{
			DICOMDIR objDICOMDIR = new DICOMDIR(strStoragePath);
			objDICOMDIR.setIDICOMDIRPathFormater(this);
			objDICOMDIR.write(objIDataSet);
		}
		catch(DICOMDIRException de)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(de.getMessage());
			}
			throw new SinkException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.StorageException", new Locale(DicomConfig.createInstance().getLocale())),de);
		}
		catch(IOException ioe)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ioe.getMessage());
			}
			throw new SinkException(ResourceBundleWrapper.getValue("exceptions", "DICOMDIR.StorageException", new Locale(DicomConfig.createInstance().getLocale())),ioe);
		}
		return true;
	}

	/**
	 * @return short - shows status value which will be used in generation of response
	 * 					Refer EnumImplOpsStatus for supported response status values.
	 */
	public short store(IQueryModel objQueryModel, String strPath)
	{
		return EnumImplOpsStatus.FAILURE.getValue();
	}
	/**
	 * This format long file names to short form.
	 * Here in the default implementation the folder structure at the Patient, Study and Series level is created by 
	 * the last eight characters of PatientName_PatientID, Study Instance UID, Series Instance UID. 
	 * The Dicom File is saved with the last eight characters of SOP Instance UID.
	 * @param strLongFileName String value containing long file name.
	 * @return String - value of formated path.
	 */
	public String formatPath(String strLongFileName)
	{
		String strRegX = File.separator;
		String strOS = System.getProperty("os.name");
		
		if(strOS.toUpperCase().contains("WINDOWS"))
		{
			strRegX = File.separator + File.separator;
		}
		else if(strOS.toUpperCase().contains("MAC") || strOS.toUpperCase().contains("LINUX"))
		{
			strRegX = File.separator;
		}
		
		String[] strArrSplitedFileName = strLongFileName.split(strRegX );
		String strStoragepath = "";

		for(int count=0; count<strArrSplitedFileName.length;count++)
		{
			String stringID = strArrSplitedFileName[count];
			stringID = stringID.replaceAll("[.=,;:\\\\/\\[]","");
			stringID = stringID.replaceAll("\\]", "");
			if(stringID.length() >8)
			{
				strStoragepath = strStoragepath +stringID.substring(stringID.length()-8,stringID.length()) + File.separator;
			}
			else
			{
				strStoragepath = strStoragepath + stringID + File.separator;
			}
		}
		strStoragepath = strStoragepath.substring(0,strStoragepath.length()-1);
		
		return strStoragepath;
	}
}
