package gov.va.med.ars.imaging;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;

import gov.va.med.ars.spring.model.ClaimAttachments;
import gov.va.med.ars.util.DateUtils;
import gov.va.med.ars.util.FileUtils;
import gov.va.med.ars.util.StringUtils;

import gov.va.med.lom.vistaLinkUtils.VistaLinkUtils;
import gov.va.med.lom.vistabroker.security.ISecurityContext;
import gov.va.med.lom.vistabroker.security.SecurityContextFactory;
import gov.va.med.vistalink.rpc.RpcRequest;
import gov.va.med.vistalink.rpc.RpcRequestFactory;
import gov.va.med.vistalink.rpc.RpcRequestParams;
import gov.va.med.vistalink.rpc.RpcResponse;


public class VistaImaging {
	private static final Log log = LogFactory.getLog(VistaImaging.class);
	static final Logger errorLogger = Logger.getLogger("errorLogger");
	static final Logger auditLogger = Logger.getLogger("auditLogger");

	/*
   This RPC accepts an array as the only input parameter. The input array used in the RPC call
     is composed of two pieces of data � a code identifying the kind of data to follow and the
   data itself. The codes used to identify the type of data correspond to the entries in the 
   table in the Input Array section.

   A node in the input array would look like: MAGDATA(n)=CODE^DATA

   MAGDATA(1)="IMAGE^\\ImageServer\ImageShare \MAX1.JPG^Image description"
   MAGDATA(2)="IMAGE^\\ImageServer\ImageShare \MAX2.JPG"
   MAGDATA(3)="IMAGE^\\ImageServer\ImageShare \MAX3.JPG^Image description"
   MAGDATA(4)="ACQD^COMPUTER CALLING RPC"
   MAGDATA(5)="ACQL^99"
   MAGDATA(6)="ACQS^688"
   MAGDATA(7)="DOCCTG^19"
   MAGDATA(8)="DOCDT^05/05/1999"
   MAGDATA(9)="IDFN^1033"
   MAGDATA(10)="STSCB^TESTCB^MAGGSIUI"
   MAGDATA(11)="TRKID^GK;101"

   Each 'IMAGE' entry is the full path of the Image using UNC notation, and optionally a 
     short description of the Image as the third �^� delimited piece.

   Input Array Descriptions:

   ACQD - Acquisition Device [required]
   Acquisition Device name must be unique for each instrument at a site. Used by the Imaging 
   Package for statistical, tracking, and debugging purposes. For Windows systems, ACQD should 
   be the "computer name" of the capturing device. For non-Windows systems, "ACQD" should be 
   the domain name of the system.

   DFLG - Delete Flag
   This parameter must be sent if the calling application wants to delete the original image 
   file(s) after being processed and copied to the Imaging Network. Possible values: "1" means 
   delete the original image(s) after processing.

   DOCCTG - Document Category (Type)
   This parameter is an IEN in the MAG DESCRIPTIVE CATEGORIES file (#2005.81), and is used to 
   identify the type of images being imported.  When DOCCTG is used, DOCDT must be used as well. 
   If DOCCTG is not used, values must be defined for PXDT, PXIEN, and PXPKG.
   Example:
   30 CLIN  GEN
   12 CLIN  OTHER-MEDICAL

   IXTYPE - Image or Document TYPE
   This is a pointer to IMAGE INDEX FOR TYPES file (#2005.83) or the full name of the Index Type.

   IXSPEC - Image or Document SPECIALTY/SUBSPECIALTY
   Pointer to IMAGE INDEX FOR SPECIALTY/SUPSPECIALTY file (#2005.84) or the full name of the Index Specialty.

   IXPROC - Image or Document PROCEDURE/EVENT
   Pointer to IMAGE INDEX FOR PROCEDURE/EVENT file (#2005.85) or the full name of the Index Proc/Event.

   IXORIGIN - Image or Document ORIGIN
   Set of Codes. Possible values are: VA, NON-VA, DOD, FEE. If a value for this is not sent, it will default to VA.

   GDESC - Group Description
   A Short Description (60 character maximum) for the group of images. Imaging generates a default description 
   if this parameter is null. The default description consists of the Procedure Name and Procedure Date.

   ITYPE - Image Type
   Use ITYPE to specify an Image Type other than the default type assumed by VistA Imaging.
   Examples:
   100  DICOM IMAGE DCM
   103  TEXT  ASC
   104  ADOBE PDF
   Typically, VistA Imaging will use the file extension of an image to determine the Image Type.

   PXIEN - Procedure IEN
   The IEN of the procedure in the VistA Package File.

   PXPKG - Procedure PKG [required]
   The File number of the VistA Package to associated with the Image. Possible values of PXPKG are "8925" or "null".
   For the current version of the Import API, images can be associated only with TIU package or as an Image Category.

   PXNEW - Procedure New
   Procedure New is a flag that determines if a new Procedure Report will be created, or if an existing one will be used.

   PXTIUTTL - TIU Title IEN or Text
   External or internal value of TIU Title in TIU DOCUMENT DEFINITION file (#8925.1), the TIU Title of a new TIU note.

   PXSGNTYP - Signature Type
     Signature Type of a new TIU Note � unsigned or electronically filed.

   PXTIUTCNT - TIU Text Lines Counter
   Text Lines counter of a new TIU Note

     PXTIUTXTnnnnn � TIU Note Text
   Text Line in newly created TIU Note

   STSCB - Status Handler [required]
   The Status Handler must be "Tag^Routine" of an M routine that exists in VistA. This is always called to inform 
   the calling package of the Status of the Import process. A Status^Message, TrackingID, and Queue Number 
   are returned and possibly a list of warnings.

   TRKID - Tracking ID [required]
   This is a unique identifier passed by the calling package. It will be saved with the IMAGE file (#2005) entry. 
   If an error occurs during processing, causing the import to fail, this number is returned along with a status
   and message to the Status Handler Routine.

   Username and Password
   Separate parameters are passed for username and encrypted password, each consisting of a string value.

   Return Parameter is an Array
   Example  : Successful Queue
    MAGRY(0)="111^Data has been Queued."
          Queue Number ^ message is returned in the (0) node.  
    No other nodes are defined.
    Example: unsuccessful Queue
    MAGRY (0)="0^Required parameter is null"
    MAGRY (1)="Tracking ID is Required. !"
    MAGRY (2)="Status Handler is Required. !"
    MAGRY (3)="Acquisition Site is Required. !"
           node (0) = 0 '^' Error message
           node(1..n)= all error messages incurred during validation

	 */
	public String importVistaImage(HttpServletRequest request, ClaimAttachments claimAttachment) {

		String response = "";  

		try {

			Date now = new Date();
			String attachment = FilenameUtils.getBaseName(claimAttachment.getAttachmentName()) + "." + 
					FilenameUtils.getExtension(claimAttachment.getAttachmentName());

			//System.out.println("Inside importVistaImage, fileName = " + attachment);

			RpcRequest req = RpcRequestFactory.getRpcRequest();

			ISecurityContext securityContext;

			req.setRpcContext("MAG WINDOWS");
			req.setRpcName("MAG4 REMOTE IMPORT");

			List<String> paramList = new ArrayList<String>();

			//RpcRequestParams params = null;
			String patientDfn = claimAttachment.getPatientIdentifier();
			String serverName = request.getServerName();
			String remotePath = FileUtils.readPropertiesFile().getProperty("ars.VI_REMOTE_PATH");
			String docType    = FilenameUtils.getExtension(attachment);
			String userName   = FileUtils.readPropertiesFile().getProperty("ars.VI_USERNAME");
			String passwd     = FileUtils.readPropertiesFile().getProperty("ars.VI_PASSWORD");
			String facilityNo = FileUtils.readPropertiesFile().getProperty("ars.VI_FACILITY_NO");
			String userDuz    = FileUtils.readPropertiesFile().getProperty("ars.VI_USERDUZ");
			String trkId = "ARS" + ";" + facilityNo + "_" +  (int)DateUtils.dateToFMDate(now) + "_" + now.getTime();

			securityContext = SecurityContextFactory.createDuzSecurityContext(facilityNo, userDuz);

			securityContext.setUserId(FileUtils.readPropertiesFile().getProperty("ars.VI_USERNAME"));
			securityContext.setDivision(FileUtils.readPropertiesFile().getProperty("ars.VI_DIVISION"));

			// Acquisition Device (computer name or domain name)
			paramList.add("ACQD^" + serverName);

			// Hospital Location
			//paramList.add("ACQL^" + acql);

			// Acquisition Site (station number)
			paramList.add("ACQS^" + facilityNo);

			// Procedure Date
			paramList.add("PXDT^" + String.valueOf(DateUtils.dateTimeToFMDateTime(now)));

			// Tracking ID
			paramList.add("TRKID^" + trkId);   

			// Status Callback
			paramList.add("STSCB^" + FileUtils.readPropertiesFile().getProperty("ars.VI_STSCB"));

			// Patient DFN
			paramList.add("IDFN^" + patientDfn);

			//Procedure Package
			paramList.add("PXPKG^8925");

			// Procedure IEN
			paramList.add("PXIEN^442");

			//paramList.add("IMAGE" + "^" + remotePath + "\\" + fileName + "^" + docType + "^" + "ARS Attachment");

			paramList.add("IMAGE" + "^" + remotePath + attachment + "^" + docType + "^" + "ARS Attachment");

			paramList.add("USERNAME^" + userName);
			paramList.add("PASSWORD^" + passwd);

			int recNum = -1;
			for(String param : paramList)
			{
				recNum=recNum+1;
				auditLogger.info("param(" + recNum + ") =  " + param);
				System.out.println("param(" + recNum + ") =  " + param);
			}

			//req.setParams(paramList);

			HashMap<String, String> map = new HashMap<String, String>();
			int i = 0;
			for (String node : paramList) {
				i++;
				map.put(String.valueOf(i), node);
			}

			List<Map> newParamList = new ArrayList<Map>();
			newParamList.add(map);

			req.setParams(newParamList);

			//RpcResponse rpcResponse = VistaLinkUtils.call(req, "442", null, "520736436");
			RpcResponse rpcResponse = VistaLinkUtils.call(req, securityContext.getDivision(), null, securityContext.getUserId());
			String results = rpcResponse.getResults();
			ArrayList<String> list = StringUtils.getArrayList(results);

			if( list != null && list.size() > 0)
			{
				response = list.get(0);
			}

			for (int k = 0; k < list.size(); k++) 
			{
				String resp = (String)list.get(k);
				System.out.println("Response :" + k+1 +  "from calling MAG4 REMOTE IMPORT RPC  = " + resp);
			}

		} 
		catch(Exception e) 
		{
			e.printStackTrace();
			errorLogger.error("Exception thrown when calling  RPC MAG4 REMOTE IMPORT : " + e.getMessage() );
			response = "Exception thrown when calling  RPC MAG4 REMOTE IMPORT : " + e.getMessage();
			return response;
		}

		return response;

	}



}
