/*******************************************************************************
 *  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.storagecommitment.testcases.defaultscp;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCommandField;
import cdac.medinfo.sdk.dcm30_04.enums.EnumLoggingLevel;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.EnumDataSink;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.EnumDataSource;
import cdac.medinfo.sdk.dcm30_04.services.dicomnetcommons.EnumServiceType;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.IDataSink;
import cdac.medinfo.sdk.dcm30_04.services.dimsecommons.IDataSource;
import cdac.medinfo.sdk.dcm30_04.services.javadbhelper.DataSinkImpl;
import cdac.medinfo.sdk.dcm30_04.services.scp.commons.ProcessHandler;
import cdac.medinfo.sdk.dcm30_04.services.scp.commons.SCPSession;
import cdac.medinfo.sdk.dcm30_04.services.storagecommitment.storagecommitmentsinkimpl.StorageCommitmentSinkImpl;
import cdac.medinfo.sdk.dcm30_04.services.storagecommitment.storagecommitmentsourceimpldb.StorageCommitmentSourceImplDB;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

/**
 * This Sample code works as Storage Commitment SCP .
 * This Sample code extends ProcessHandler class which is default implementation 
 * of SDK to process all kinds of Association and Service Request.
 * Once the required parameters are given to the ProcessHandler and is started , 
 * it is capable of process all association and service requests and sending their response
 *  N-Event Report Server information should be set in Storage Commitment SCP to send N-Event Report of Storage
 * Commitment Operation.
 * The IP and port on which this server is started should also be provided to Storage Commitment SCP.
 *  To create DB for Storage Commitment  refer SQL Script DICOMServerDB.sql provided in install. 
 */
public class StorageCommitment_SCP_Def_ProcHandler
{
	public static void main(String[] args) 
	{
		try
		{
			DicomConfig objDicomConfig = DicomConfig.createInstance();
			//Enables logging mode in SDK. In SEVERE logging level
			//Exceptions are logged.
			objDicomConfig.enableLogging(EnumLoggingLevel.SEVERE,"C:\\DCM_Logs");


			/*
			 * Creates StorageCommitmentHandler.
			 */
			StorageCommitmentHandler scp = new StorageCommitmentHandler();

			/*
			 * Start Storage Commitment Server.
			 */
			scp.doStorageCommitment();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

/**
 * This class inherits all the lifecycle methods involved in a communication with client.
 * This class is extened from the ProcessHandler class of the SDK for DICOM.
 * ProcessHandler class is the default processor of SDK for DICOM which is capable
 * of handling connection , association and serive requests. It process all the request , 
 * generates response and sents it to SCU.
 * Once the required parameters are set on ProcessHandler class of SDK for DICOM
 * then it will handle all the Association and Service requests.
 */
class StorageCommitmentHandler extends ProcessHandler
{
	public void doStorageCommitment() 
	{
		try
		{
			/*
			 * DataBase path.
			 */
			String dataBasePath = "C:/Database/SDKDatabase/SDKdb";
			String ConnectionString = "jdbc:derby://localhost:5050/" + dataBasePath;
			String driverString = "org.apache.derby.jdbc.ClientDriver";

			/*
			 * Add DataSink for C-Store and Storage Commitment.
			 */
			IDataSink objSCDataSink = new StorageCommitmentSinkImpl();
			IDataSink objCServicesDataSink = new DataSinkImpl(ConnectionString,driverString);
			IDataSource objSCDataSource = new StorageCommitmentSourceImplDB(ConnectionString,driverString);

			/*
			 * Add DataSource and DataSink to process handler.
			 */
			addDataSink(EnumDataSink.CSERVICES, objCServicesDataSink);
			addDataSink(EnumDataSink.STORAGE_COMMITMENT_PUSH_MODEL, objSCDataSink);
			addDataSource(EnumDataSource.STORAGE_COMMITMENT_PUSH_MODEL, objSCDataSource);

			/*
			 * Alternatively User can  use StorageCommitmentSourceImplDicomDir.
			 * instead of Db.
			 * IDataSource objDataSource =new StorageCommitmentSourceImplDICOMDIR("D:\\DICOMDIRPATH");
			 * addDataSource(EnumDataSource.STORAGE_COMMITMENT_PUSH_MODEL, objDataSource);
			 */

			/*
			 * Add N-Event Report SCP IP, Port information.
			 * The Storage Commitment SCP sends N-Event Report
			 * Request to the Event SCP.
			 */
			addNEventReportSCPInformation("SDK", "localhost", 9999);
			addNEventReportSCPInformation("DCMRCV", "localhost",9002);

			/*
			 * Configure the path to store DataSet for which Storage Commitment
			 * is to be provided. If this path is not set then the files are not
			 * moved from the server.
			 */
			setStorageCommitmentPath("C:\\StorageCommitmentPath");

			//Create SCP Session 
			SCPSession session = new SCPSession();

			//Set Process Handler as the SCP TestCode
			session.setIProcessHandler(this);
			
			/*
			 * Setting time out as 5000 milli second. It will wait 5000 mili seconds for read and write operation.
			 * If in the time specified (5000 ms) read or write operation is not performed then 
			 * session is time out.
			 */ 
			//session.setTimeOut(5000);

			/*
			 * Initializing selected services on SCPSession.
			 * This selection customises assocaition loading process where the association context related to
			 * selected services will only be loaded for negotiation purpose.
			 */
			EnumServiceType []arrenumServiceType = new EnumServiceType[2];
			arrenumServiceType[0] = EnumServiceType.NACTION_STORAGE_COMMITMENT;
			arrenumServiceType[1] = EnumServiceType.CSTORE_DEFAULT;
			session.selectServices(arrenumServiceType);

			/*
			 * Set EnumCommandFiled on ProcessHandler. The procesHandler will process the services whose
			 * command field is set in Processhandler. For the request of other services the process handler
			 * will generate Abort.
			 */
			ISingleCollection<EnumCommandField> objEnumCommandField = new SingleCollection<EnumCommandField>();
			objEnumCommandField.add(EnumCommandField.C_STORE_RQ);
			objEnumCommandField.add(EnumCommandField.N_ACTION_RQ);
			setEnumCommandField(objEnumCommandField);

			//Start the Session
			session.start("SDK",9001);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}




