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

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;

/**
 * This class provides implementation of DataBase Connection and processing of queries on DataBase.
 * NService_DBAgent is a singleton class.
 * NService_DBAgent provides the support to create, update and retrieve information of a SOP Instance.
 */
public class NService_DBAgent 
{
	private NService_DBQuery objNService_DBQuery=null;
	private static String dbURL = null;
	private static String emdriver = null;
	private static Connection objcon = null;
	private static NService_DBAgent objMPPSDBAgent = null;
	private static Object mutex = new Object();


	/**
	 * Default Private Constructor
	 * @param strConnectionString 
	 * @param strDriverName
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	private NService_DBAgent(String strConnectionString, String strDriverName)throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException
	{
		emdriver = new String(strDriverName);
		dbURL = new String(strConnectionString);
		// System.out.println("Loading the driver...");
		Class.forName(emdriver).newInstance();
		// System.out.println("Getting  database connection...");
		objcon = DriverManager.getConnection(dbURL);
		// System.out.println("Connection established");
		objNService_DBQuery = new NService_DBQuery();
		objNService_DBQuery.setConnection(objcon);
	}

	/**
	 * Creates instance of NService_DBAgent.
	 * @return NService_DBAgent object of NService_DBAgent
	 * @throws SQLException Signals if SQL Exception occurs.
	 * @throws ClassNotFoundException if ClassNotFoundException occurs
	 * @throws InstantiationException if InstantiationException occurs
	 * @throws IllegalAccessException if IllegalAccessException occurs
	 */
	public static NService_DBAgent createInstance(String strConnectionString, String strDriverName)throws SQLException,ClassNotFoundException, InstantiationException, IllegalAccessException
	{
		synchronized (mutex) 
		{
			if(objMPPSDBAgent == null)
				objMPPSDBAgent = new NService_DBAgent(strConnectionString,strDriverName);
		}
		return objMPPSDBAgent;
	}

	/**
	 * Creates SOP Instance for provided SOPInstanceUID and DataElement attributes.
	 * @param objIDataSet instance of Dataset
	 * @param strSOPInstanceUID value of SOPInstanceUID
	 * @return boolean - status as true or false
	 * @throws SQLException if SQL operation fails
	 */
	public boolean createSOPInstance(IDataSet objIDataSet,String strSOPInstanceUID)throws SQLException
	{
		return (objNService_DBQuery.createSOPInstance(objIDataSet, strSOPInstanceUID));
	}

	/**
	 * Updates a SOP Instance
	 * @param objIDataSet instance of Dataset
	 * @param strSOPInstanceUID value of SOPInstanceUID
	 * @return boolean - status as true or false
	 * @throws SQLException if SQL operation fails
	 */
	public boolean updateSOPInstance(IDataSet objIDataSet,String strSOPInstanceUID)throws SQLException
	{
		return objNService_DBQuery.updateMPPSInstanceInfo(objIDataSet, strSOPInstanceUID);
	}

	/**
	 * Retrieves a SOP Instance
	 * @param objIDataSet instance of Dataset
	 * @param strSOPInstanceUID value of SOPInstanceUID
	 * @return IDataSet - instance of resultant Dataset 
	 * @throws SQLException if SQL operation fails
	 */
	public IDataSet retrieveSOPInstance(ISingleCollection<ITag> objTagCollection,String strSOPInstanceUID)throws SQLException
	{
		return objNService_DBQuery.retrieveMPPSInstanceInfo(objTagCollection, strSOPInstanceUID);
	}
	
	/**
	 * Retrieves the value of Performed Procedure Step Status Value.
	 * @param iGroupNo Group Number of attribute
	 * @param iElementNo Element Number of Attribute
	 * @param strSOPInstanceUID value of SOP Instance UID 
	 * @return String value of step status.
	 * @throws SQLException if sql operation fails
	 */
	public String isUpdationAllowed(int iGroupNo,int iElementNo, String strSOPInstanceUID)throws SQLException
	{
		return objNService_DBQuery.isUpdationAllowed(iGroupNo, iElementNo, strSOPInstanceUID);
	}
	
	/**
	 * Checks whether provided SOP Instance is created or not.
	 * @param strSOPInstance value of SOP Instance UID 
	 * @return boolean shows status as success or failure
	 * @throws SQLException if sql operation fails
	 */
	public boolean isSOPInstanceExist(String strSOPInstance)throws SQLException
	{
		return objNService_DBQuery.isSOPInstanceExist(strSOPInstance);
	}

	/**
	 * Close data base connection.
	 */
	public void close() throws SQLException
	{
		objcon.close();
	}	
}
