/*******************************************************************************
 *  Copyright 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.generalpurposemimeinterchangeprofile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;

import cdac.medinfo.sdk.dcm30_04.baselibs.SQ;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.services.generalpurposecompressioninterchangeprofiles.MediaStorageUncompresse_FSR;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;
import cdac.medinfo.sdk.dcm30_04.utils.ICollectionIterator;
import cdac.medinfo.sdk.dcm30_04.utils.ResourceBundleWrapper;
import cdac.medinfo.sdk.dcm30_04.utils.StandardMethods;
/**
 * This class is implemented to use DIMSE_M-Services.
 * The MediaStorageMail_FSR supports the Media Storage Operations M-Read and M-Inquire File .
 * It Receives Dicom-Dir File set by mail.
 * */
public class MediaStorageMail_FSR 
{
	/**
	 * This function Receives DicomDir File Set.
	 * It fetches data from DicomDir File-Set.
	 * It creates object of MediaStorage_uncompresse_FSR and calls process function of MediaStorage_uncompresse_FSR.
	 * @param username, password
	 * @throws IOException 
	 * @throws MessagingException, IOException
	 * */
	public void process(String username ,String password) throws MessagingException, IOException 
	{
		receiveemail(username,password);
	}
	/**
	 * This function Receives DicomDir File Set from mail.
	 * It downloads DicomDir File Set from mail.
	 * @param username, password
	 * @throws MessagingException, IOException
	 * */
	public static String receiveemail(String username ,String password) throws MessagingException, IOException

	{	
		String filenamecompress = null;
		if(username == null||username == "" ||username == "null"||username.isEmpty()||password == null||password == "" ||password == "null"||password.isEmpty())
		{
			DicomLogger.getLogger().log(ResourceBundleWrapper.getValue("warning", "PrimaryAttributeMissing", new Locale(DicomConfig.createInstance().getLocale())));
		}
		else
		{
			Properties props = System.getProperties();
			InputStream input = MediaStorageMail_FSC.class.getResourceAsStream("email_configuration.properties");
			props.load(input);
			String imapstarttls =props.getProperty("imapstarttls"); 
			props.put("mail.imap.starttls.enable", imapstarttls);
			String imapsocketFactory =props.getProperty("imapsocketFactory"); 
			props.setProperty("mail.imap.socketFactory.fallback", imapsocketFactory);
			String imapport =props.getProperty("imapport"); 
			props.setProperty("mail.imap.port", imapport);
			String imapsocketFactoryport =props.getProperty("imapsocketFactoryport");
			props.setProperty("mail.imap.socketFactory.port", imapsocketFactoryport);
			String hostnew =  "imap-mail."+props.getProperty("imapshost")+".com";
			props.put("mail.imap.host",hostnew);
			Session session = Session.getDefaultInstance(System.getProperties(), null);
			Store store = session.getStore("imap");
			String hostname =  "imap."+props.getProperty("imapshost")+".com";
			store.connect(hostname,143, username, password);
			DicomLogger.getLogger().log(ResourceBundleWrapper.getValue("status", "ConnectionEstablished", new Locale(DicomConfig.createInstance().getLocale())) );
			Folder emailFolder = store.getFolder("INBOX");
			emailFolder.open(Folder.READ_ONLY);
			// retrieve the messages from the folder in an array and print it
			Message[] messages = emailFolder.getMessages();
			DicomLogger.getLogger().log("messages.length---" + messages.length);
			for (int i = 0; i < messages.length; i++) 
			{
				Message message = messages[i];
				String folderName = StandardMethods.getTempDirectoryStorage();
				filenamecompress = saveparts(message.getContent(), folderName);
				if(filenamecompress.isEmpty()||filenamecompress.equalsIgnoreCase("")||filenamecompress == "null"||filenamecompress==null)
				{
					DicomLogger.getLogger().log(ResourceBundleWrapper.getValue("warning", "DICOMDIR.FileNotFound", new Locale(DicomConfig.createInstance().getLocale())));
				}
				else
				{
					MediaStorageUncompresse_FSR objMediaStorage_uncompresse_FSR = new MediaStorageUncompresse_FSR();
					String destDir =StandardMethods.getTempDirectoryStorage();
					IDataSet objIDataSet= objMediaStorage_uncompresse_FSR.process(filenamecompress, destDir);
					if(objIDataSet == null||objIDataSet.isEmpty())
					{
						DicomLogger.getLogger().log(ResourceBundleWrapper.getValue("warning", "DICOMDIR.FileNotFound", new Locale(DicomConfig.createInstance().getLocale())));
					}
					else
					{
						display(objIDataSet);
					}
				}
			} 
			// close the store and folder objects
			emailFolder.close(false);
			store.close();}
		return filenamecompress;
	}
	/**
	 * This function checks mail having attachments.
	 * It saves attachments of mail.
	 * @param content,filename
	 * @throws MessagingException, IOException
	 * */
	public static String saveparts(Object content, String folderName) throws IOException, MessagingException
	{
		String fileName="";	
		OutputStream objOutputStream = null;
		InputStream objInputStream = null;
		try 
		{
			if(content instanceof Multipart)
			{
				Multipart objMultipart = ((Multipart)content);
				int parts = objMultipart.getCount();
				for (int j=1; j < parts; ++j) 
				{
					MimeBodyPart part = (MimeBodyPart)objMultipart.getBodyPart(j);
					if(part.getContent() instanceof Multipart) 
					{
						// part-within-a-part, do some recursion.
						saveparts(part.getContent(), folderName);
					}
					else 
					{
						String attachmentName = null;
						if (!part.isMimeType("text/html")||!part.isMimeType("text/plain"))
						{
							// Try to get the name of the attachment
							attachmentName = part.getDataHandler().getName();
							if(attachmentName !=  null) 
							{
								fileName = folderName + "\\" + attachmentName;
								DicomLogger.getLogger().log(folderName);
								objOutputStream = new FileOutputStream(new File(fileName));
								objInputStream = part.getInputStream();
								int k;
								while((k = objInputStream.read()) != -1)
								{
									objOutputStream.write(k);
								}
							}
						}
					}
				}
			}
		}
		finally 
		{
			if(objInputStream != null) 
			{ 
				objInputStream.close(); 
			}
			if(objOutputStream != null) 
			{ 
				objOutputStream.flush();
				objOutputStream.close(); }
		}
		return fileName;
	}

	/**
	 * Displays the DataElements of Dataset
	 */
	public static void display(IDataSet  objIdataset)

	{

		ICollectionIterator<IDataElement> objIDataSetIterator = objIdataset.iterator();

		System.out.println("Tag     Value");
		while(objIDataSetIterator.hasNext())
		{
			IDataElement objDataElement = objIDataSetIterator.next();				

			if(!(objDataElement.getDicomValue() instanceof SQ))
			{

				System.out.println(objDataElement.getTag().getGroupNumber()+"    "+
						objDataElement.getTag().getElementNumber()+"    "+
						objDataElement.getDicomValue().toString());
			}
			else  
			{
				System.out.println("else part");
				displaySequence((SQ)objDataElement.getDicomValue(),"> ");					
			}
		}
	}

	/**
	 * Displays the Dicom Data SQ.
	 */
	public static void displaySequence(SQ objSQDataElement,String ss)

	{
		ICollectionIterator<IItem> objSQItemIterator = objSQDataElement.iterator();
		int i = 1;
		while(objSQItemIterator.hasNext())
		{
			System.out.println("ITEM :"+ i++ );
			IItem objItem = objSQItemIterator.next();
			ICollectionIterator<IDataElement> objDataElementIterator = objItem.iterator();
			while(objDataElementIterator.hasNext())
			{
				IDataElement objDataElement = objDataElementIterator.next();

				if(!(objDataElement.getDicomValue() instanceof SQ))
				{
					System.out.println(ss +objDataElement.getTag().getGroupNumber()+"    "+
							objDataElement.getTag().getElementNumber()+"    "+
							objDataElement.getDicomValue().toString());						 
				}
				else
				{
					displaySequence((SQ)objDataElement.getDicomValue(),ss+ss);
				}	 
			}
		}}
}