/*******************************************************************************
 *  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.tlsscu.commons;

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


import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.DicomMessage;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.ServiceAgent;
import cdac.medinfo.sdk.dcm30_04.services.pdu.PDUReader;
import cdac.medinfo.sdk.dcm30_04.services.pdu.PDUWriter;
import cdac.medinfo.sdk.dcm30_04.services.scu.commons.ClientSideAssociationAgent;
import cdac.medinfo.sdk.dcm30_04.services.scu.commons.SCUSession;
import cdac.medinfo.sdk.dcm30_04.services.tls.commons.TLSClientConfig;
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;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;



/**
 * This class establishes TLS SCU Session with the remote entity.
 * This class act as a data notification receiver. When ever data arrives from the remote
 * application entity is is notified to TLS SCU Session. It also listen for the connection status.
 * If the connection does not exits then TLS SCU session is stopped.
 */
public class TLSSCUSession extends SCUSession
{

	

	/**
	 * Instantiates a new TLS SCU session.
	 * @throws IOException
	 */
	public TLSSCUSession() throws IOException
	{
		super();
	}


	/**
	 * Start the secure TLS SCU session with Socket Address, in case of specified 
	 * TLS configuration is NULL session is insecure.
	 * @param addr instance of IP Socket Address
	 * @param objTLSClientConfig configuration of TLS client.
	 * @throws IOException  Signals that an I/O exception has occurred.
	 */
	public void start(InetSocketAddress addr, TLSClientConfig objTLSClientConfig) throws IOException
	{
		this.objInetSocketAddress = addr;
		if(null != objTLSClientConfig)
		{
			if(!isConnected)
			{
				objDIMSERQCollection = new SingleCollection<DicomMessage>();
				objMsgIDCollection = new SingleCollection<Short>();	

				TLSClientSideNetworkAgent objClientSideNetworkAgent = new TLSClientSideNetworkAgent();
				super.objNetworkAgent = objClientSideNetworkAgent;

				objClientSideNetworkAgent.connect(addr,objTLSClientConfig,itimeout);
				setSecured(true);

				pduReader = new PDUReader(objClientSideNetworkAgent);
				pduWriter = new PDUWriter(objClientSideNetworkAgent);

				objClientSideAssociationAgent = new ClientSideAssociationAgent(pduWriter,pduReader);
				objClientSideAssociationAgent.addDataNotificationListener(this);
				pduReader.addAssociatePDUReceiver(objClientSideAssociationAgent);

				//add SCUSession as Connection Listener on PDUWritter and PDUReader.
				pduReader.addConnectionListener(this);
				pduWriter.addConnectionListener(this);
				pduReader.setPduWriter(pduWriter);

				objServiceAgent = new ServiceAgent(pduWriter);
				objServiceAgent.addDataNotificationListener(this);
				pduReader.addServicePDUReceiver(objServiceAgent);

				objClientSideAssociationAgent.addAssociationStatusListener(objServiceAgent);
				isConnected = true;
				pduReader.start();
				if(DicomConfig.createInstance().isLoggingOn())
				{
					DicomLogger objDicomLogger = DicomLogger.getLogger();
					objDicomLogger.log(ResourceBundleWrapper.getValue("status", "TLSConnectionEstablished",new Locale(DicomConfig.createInstance().getLocale())));
				}
			}
			else
			{
				if(DicomConfig.createInstance().isLoggingOn())
				{
					DicomLogger objDicomLogger = DicomLogger.getLogger();
					objDicomLogger.log(ResourceBundleWrapper.getValue("warning", "TLSSCUSessionAlreadyConnected",new Locale(DicomConfig.createInstance().getLocale())));
				}
			}	
		}
		else	
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger objDicomLogger = DicomLogger.getLogger();
				objDicomLogger.log(ResourceBundleWrapper.getValue("warning", "TLSClientConfigNULL",new Locale(DicomConfig.createInstance().getLocale())));
			}
			super.start(addr);
		}
	}


	/**
	 * Start the secure TLS SCU session with the IP and port given, in case of specified 
	 * TLS configuration is NULL session is insecure.
	 * @param strIP String value of IP.
	 * @param iPort int value of port.
	 * @param objTLSClientConfig configuration of TLS client.
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void start(String strIP, int iPort,TLSClientConfig objTLSClientConfig) throws IOException
	{
		start(new InetSocketAddress(strIP,iPort),objTLSClientConfig);
	}	
}
