package unitTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

import javax.swing.ImageIcon;

import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException;

import netsdk.callback.SUBSCRIBE_CALLBACK;
import netsdk.callback.impl.SUBSCRIBE_CALLBACK_IMPL;
import netsdk.lib.CommonFunctions;
import netsdk.lib.DeviceSdk;
import netsdk.lib.ErrorCodeAndConst;
import netsdk.struct.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;



import java.awt.image.BufferedImage; 
public class NET_SDK_A2IPC_Test {
	public static NativeLong loginId;
	public static String targetInfo;
	public static boolean m_SubscribFaceMatch;//是否订阅人脸报警
	public static boolean m_SubscribFaceDetect;//是否订阅人脸检测
	public static String m_serverAddressVFD;//
	public static SUBSCRIBE_CALLBACK FaceAlarmCB;
	public static LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo;
	/**
	 * 初始化，登录
	 * 
	 * @Title: A
	 * @Description: TODO
	 * @return: void
	 */
	//@Test
	public void A() throws Throwable{
		Boolean initResult = CommonFunctions.init();
		if(!initResult)
			return;
		else {
			
			lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();			
			loginId = CommonFunctions.login(lpDeviceInfo);
			System.out.println("设备id是：" + lpDeviceInfo.deviceID);
			try {
				String name = new String(lpDeviceInfo.deviceName, "GB2312");
				System.out.println("设备名称是：" + name);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("设备mac是：" + CommonFunctions.GetDeviceMAC(lpDeviceInfo.deviceMAC));
			;
			
			// 释放内存
			Pointer p = lpDeviceInfo.getPointer();
			long peer = Pointer.nativeValue(p);
			Native.free(peer);// 手动释放内存
			Pointer.nativeValue(p, 0);
			try {
				Thread.sleep(1000L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	/**
	 *   按A2 IPC目标库人脸ID获取详细信息
	 * @Title: B
	 *
	 * */
	//@Test
	public void B() {
		if(loginId == null||loginId.intValue() < 1) {
			try {
				A();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		String res = "";
		String num = "";
		String szUrl = "GetTargetFace";
		String sendXml = "<?xml version = '1.0' encoding='utf-8'?>" +
                                        "<config version='1.7' xmlns='http://www.ipc.com/ver10'>" +
                                        "<types><queryType><enum>byPersonID</enum>" + 
                                        "<enum>byListType</enum><enum>byName</enum>" +
                                        "<enum>byIdentifyNumber</enum></queryType><listType>" +
                                        "<enum>strangerList</enum><enum>whiteList</enum>" +
                                        "<enum>blackList</enum></listType></types></config>";
		IntByReference lpBytesReturned = new IntByReference();
		Pointer pNativeData = new Memory(1024 * 1024); 
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if(ret) {
			int vesionLen = lpBytesReturned.getValue();			
        	byte[] byteArray = pNativeData.getByteArray(0, vesionLen);       	
			String resXml = new String(byteArray);
			System.out.println(resXml);        	
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);
	}
	/**
	 * 获取A2 IPC人脸目标信息
	 * @Title: C
	 *
	 * */
	//@Test
	public void C() throws Throwable{
		
		IPC_FACE_INFO resFace = new IPC_FACE_INFO();
		int id = 1595388884;//此id从上面返回的xml中提取
		String res = "";
        String szUrl = "GetTargetFace";
        String tempXML = "<?xml version = '1.0' encoding='utf-8'?>" +
                                            "<config version='1.7' xmlns='http://www.ipc.com/ver10'>" +
                                            "<types>" + 
                                                "<queryType>" + 
                                                  "<enum>byPersonID</enum>" +  
                                                  "<enum>byListType</enum>" +  
                                                  "<enum>byName</enum>" +  
                                                  "<enum>byIdentifyNumber</enum>" + 
                                                "</queryType>" +  
                                                "<listType>" + 
                                                  "<enum>strangerList</enum>" +  
                                                  "<enum>whiteList</enum>" +  
                                                  "<enum>blackList</enum>" + 
                                                "</listType>" + 
                                              "</types>" +  
                                              "<queryAction>" + 
                                                "<queryType type='queryType'>byPersonID</queryType>" +  
                                                "<personID type='uint32'>%d</personID>" + 
                                              "</queryAction>" + 
                                            "</config>";        
        String sendXml = String.format(tempXML, id);
        IntByReference lpBytesReturned = new IntByReference();
        Pointer pNativeData = new Memory(1024 * 1024); 
        
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if (ret)
        {
        	int vesionLen = lpBytesReturned.getValue();       	
        	byte[] byteArray = pNativeData.getByteArray(0, vesionLen);
        	String resXml = new String(byteArray);
			System.out.println(resXml);	
			
			targetInfo = resXml;
			
			
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);
		

	}
	/**
	 * 添加A2 IPC目标信息
	 * @Title: D
	 *
	 * */
	@Test
	public void D()  throws Throwable{
		String szUrl = "AddTargetFace";
		String tempXML = "<?xml version = '1.0' encoding='utf-8'?>" +
                                        "<config version='1.7' xmlns='http://www.ipc.com/ver10' >" +
                                        "<types>" +
                                        "<listType> " +
                                          "<enum>strangerList</enum>" + 
                                          "<enum>whiteList</enum>" +  
                                          "<enum>blackList</enum>" + 
                                        "</listType>" +  
                                        "<sexType>" + 
                                          "<enum>male</enum>" +  
                                          "<enum>female</enum>" + 
                                        "</sexType>" +  
                                        "<formatType>" + 
                                          "<enum>jpg</enum>" +                                         
                                        "</formatType>" + 
                                        "</types>" +
                                        "<personInfo>" +
                                        "<listType type='listType'>%s</listType>" + //目标类型，白名单或者黑名单
                                        "<name type='string' maxLen='127'><![CDATA[%s]]></name>" +  //此处名称为UTF8格式字符串
                                        "<sex type='sexType'>%s</sex>" +
                                        "<age type='uint32'>%d</age>" +
                                        "<identifyNumber type='string' maxLen='127'><![CDATA[%s]]></identifyNumber>" +
                                        "<telephone type='string' maxLen='63'><![CDATA[%s]]></telephone>" +                                       
                                        "</personInfo>" +
                                        "<faceImgs type='list' maxCount='5' count='%d'>" +  //图片张数
                                        "<item>" +
                                        "<pictureData><![CDATA[%s]]></pictureData>" +  //图片数据，Base64String
                                        "<pictureNum>%d</pictureNum>" +
                                        "<Width>%d</Width>" +
                                        "<Height>%d</Height>" +  
                                        "<Height>%d</Height>" +
                                        "<format>%s</format>" +  //图片格式，"jpg"
                                        "<size>%d</size>" +
                                        "</item>" +
                                        "</faceImgs>" +
                                    "</config>";		
		
		byte[] nameArr = "1".getBytes("UTF-8");
		String listType = "whiteList";
		String name = new String(nameArr);
		//String name = "333";
		String sex = "female";
		int age = 18;
		String identifyNumber = "1";
		String telephone = "1";
		int count = 1;
		String pictureData = CommonFunctions.getImageStr("C:\\Users\\8590\\Desktop\\ddn.jpg");
		//String pictureData ="";
		int pictureNum = 1;
		ImageIcon imageIcon = new ImageIcon("C:\\Users\\8590\\Desktop\\ddn.jpg"); 
		int Width = imageIcon.getIconWidth(); 
		int Height = imageIcon.getIconHeight();
		String format = "jpg";
		int size = CommonFunctions.pathSize("C:\\Users\\8590\\Desktop\\ddn.jpg");

//		String sendXml = String.format(tempXML, listType,name,sex,age,identifyNumber,telephone,count,
//				pictureData,pictureNum,Width,Height,Height,format,size);
		String sendXml = String.format(tempXML, listType,name,sex,age,identifyNumber,telephone,count,
				pictureData,pictureNum,Height,Width,Width,format,size);
		System.out.println(sendXml);
		//String sendXml = targetInfo.replaceFirst("<sex type=\"sexType\">male</sex>", "<sex type=\"sexType\">female</sex>");
		IntByReference lpBytesReturned = new IntByReference();
		Pointer pNativeData = new Memory(1024 * 1024); 	       
		//boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, tempXML, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if (ret)
        {

        	byte[] data = pNativeData.getByteArray(0, lpBytesReturned.getValue());
        	String temp = CommonFunctions.ByteToStr(data,"UTF8");  
			System.out.println(temp);								
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);				
//		File saveFile = new File("D:\\1.jpg");
//        FileInputStream saveInputStream = new FileInputStream(saveFile);
//        long facePicSize = saveFile.length();
        
        

	}
	
	
	/**
	 * 编辑A2 IPC目标信息
	 * @Title: E
	 *
	 * */
	//@Test
	public void E() {
		String szUrl = "EditTargetFace";
		String sendXml = targetInfo;
		String regex = "<listType type=\"listType\">whiteList</listType>";
		String replacement = "<listType type=\"listType\">blackList</listType>";
		sendXml = sendXml.replaceFirst(regex, replacement);
		
		IntByReference lpBytesReturned = new IntByReference();
		Pointer pNativeData = new Memory(1024 * 1024); 	        
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if (ret)
        {
			System.out.println("编辑目标成功");								
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);		
	}
	/**
	 * 删除A2 IPC目标信息
	 * @Title: F
	 *
	 * */
	//@Test
	public void F() {
		int id = 1552419696;//要删除的目标id
		 String szUrl = "DeleteTargetFace";
		 String tempXML = "<?xml version = '1.0' encoding='utf-8'?>" +
                                         "<config version='1.7' xmlns='http://www.ipc.com/ver10'>" +
                                         "<types>" + 
                                             "<deleteType>" + 
                                               "<enum>byPersonID</enum>" +  
                                               "<enum>byListType</enum>" +  
                                               "<enum>byName</enum>" +  
                                               "<enum>byIdentifyNumber</enum>" + 
                                             "</deleteType>" +  
                                             "<listType>" + 
                                               "<enum>strangerList</enum>" +  
                                               "<enum>whiteList</enum>" +  
                                               "<enum>blackList</enum>" + 
                                             "</listType>" + 
                                           "</types>" +  
                                           "<deleteAction>" + 
                                             "<deleteType type='deleteType'>byPersonID</deleteType>" +  
                                             "<personID type='uint32'>%d</personID>" + 
                                           "</deleteAction>" + 
                                         "</config>";
		 String sendXml = String.format(tempXML, id);

        IntByReference lpBytesReturned = new IntByReference();
        Pointer pNativeData = new Memory(1024 * 1024); 
        
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if (ret)
        {
			System.out.println("删除目标成功");									
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);
	}
	
	/**
	 * 查询指定时间范围内的抓拍人脸关键字
	 * @Title: G
	 *
	 * */
	//@Test
	public void G() {
		
         String starttime = "2019-06-04 00:00:00";
         String endtime = "2019-06-04 23:59:59";
		 String szUrl = "SearchSnapFaceByTime";
		 String tempXML = "<?xml version = '1.0' encoding='utf-8'?>" +
                                         "<config version='1.7' xmlns='http://www.ipc.com/ver10'>" +
                                         "<search>" + 
                                             "<starttime type='string'><![CDATA[%s]]></starttime>" +  
                                             "<endtime type='string'><![CDATA[%s]]></endtime>" + 
                                         "</search>" + 
                                     "</config>";

		 String sendXml = String.format(tempXML, starttime, endtime);
		 
		 IntByReference lpBytesReturned = new IntByReference();
		Pointer pNativeData = new Memory(1024 * 1024); 
        boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
        if(ret) {
			int vesionLen = lpBytesReturned.getValue();			
        	byte[] byteArray = pNativeData.getByteArray(0, vesionLen);       	
			String resXml = new String(byteArray);
			System.out.println(resXml);        	
        }
     // 释放内存
		long peer = Pointer.nativeValue(pNativeData);
		Native.free(peer);// 手动释放内存
		Pointer.nativeValue(pNativeData, 0);
	}
	
	
	/**
	 * 按抓拍人脸关键字获取详细信息
	 * @Title: H
	 *
	 * */
	//@Test
	public void H() {
		String szUrl = "SearchSnapFaceByKey";
		String tempXML = "<?xml version = '1.0' encoding='utf-8'?>" +
                                     "<config version='1.7' xmlns='http://www.ipc.com/ver10'>" +
                                     "<search>" + 
                                     "<snapTime type='uint64'>%d</snapTime>" +  
                                     "<faceID type='uint32'>%d</faceID>" +  
                                     "<requestPanoramicPic type='boolean'>true</requestPanoramicPic>" +  
                                     "<requestPersonPic type='boolean'>true</requestPersonPic>" + 
                                   "</search>" + 
                                 "</config>";
		
		String snapTime = "2019-06-11 00:00:00";
		long iTime = CommonFunctions.dateToStamp(snapTime);//此抓拍时间应该从SearchSnapFaceByTime返回的结果去取
		int faceID = 1552419696;//此id应该从SearchSnapFaceByTime返回的结果去取
         String sendXml = String.format(tempXML, snapTime, faceID);
         IntByReference lpBytesReturned = new IntByReference();
 		Pointer pNativeData = new Memory(1024 * 1024); 
         boolean ret = DeviceSdk.INSTANCE.NET_SDK_TransparentConfig(loginId, sendXml, szUrl, pNativeData, 1024 * 1024, lpBytesReturned);
         if(ret) {
 			int vesionLen = lpBytesReturned.getValue();			
         	byte[] byteArray = pNativeData.getByteArray(0, vesionLen);       	
 			String resXml = new String(byteArray);
 			System.out.println(resXml);        	
         }
      // 释放内存
 		long peer = Pointer.nativeValue(pNativeData);
 		Native.free(peer);// 手动释放内存
 		Pointer.nativeValue(pNativeData, 0);
	}
	/**
	 * 订阅报警
	 * @Title: SubscribAlarm
	 *
	 * */
	//@Test
	public void SubscribAlarm() {
		if(loginId == null||loginId.intValue() < 1) {
			try {
				A();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		int chn = 0;//IPC通道一般为0
		NET_DVR_SUBSCRIBE_REPLY.ByReference sSmartSubscrib = new NET_DVR_SUBSCRIBE_REPLY.ByReference();
		
		int index = intelist.intelist_Vfd.ordinal();
		if(((lpDeviceInfo.function[0] & (1<<index)) >> index == 1) && (lpDeviceInfo.deviceType ==  2)){
			if(!m_SubscribFaceDetect) {
				boolean ret = DeviceSdk.INSTANCE.NET_SDK_SmartSubscrib(loginId, ErrorCodeAndConst.NET_DVR_SMART_VFD, chn, sSmartSubscrib);
				if(ret) {
					m_SubscribFaceDetect = true;
				}
			}
		}
		
		index = intelist.intelist_Vfd_Match.ordinal();
		if(((lpDeviceInfo.function[0] & (1<<index)) >> index == 1) && (lpDeviceInfo.deviceType ==  2)) {
			if(!m_SubscribFaceMatch) {
				boolean ret = DeviceSdk.INSTANCE.NET_SDK_SmartSubscrib(loginId, ErrorCodeAndConst.NET_DVR_SMART_VFD_MATCH, chn, sSmartSubscrib);
				if(ret) {
					m_SubscribFaceMatch = true;
					m_serverAddressVFD = new String(sSmartSubscrib.serverAddress);
					System.out.println(m_serverAddressVFD);
				}
			}
		}
								
	}
	/**
	 * 取消订阅报警
	 * @Title: UnSubscribAlarm
	 *
	 * */
	//@Test
	public void UnSubscribAlarm() {	
		if(m_SubscribFaceMatch) {
			int chn = 0;//IPC通道一般为0
			NET_DVR_SUBSCRIBE_REPLY.ByReference sSmartSubscrib = new NET_DVR_SUBSCRIBE_REPLY.ByReference();
			byte[] sb = m_serverAddressVFD.getBytes();
			Pointer pNativeData = new Memory(sb.length); 
			pNativeData.write(0, sb, 0, sb.length);		
			IntByReference dwResult = new IntByReference();
			boolean ret = DeviceSdk.INSTANCE.NET_SDK_UnSmartSubscrib(loginId, 2, chn, pNativeData, dwResult);
			if(ret) {
				m_SubscribFaceMatch = false;
				System.out.println("取消订阅报警成功");
			}
			// 释放内存
					long peer = Pointer.nativeValue(pNativeData);
					Native.free(peer);// 手动释放内存
					Pointer.nativeValue(pNativeData, 0);
		}
		if(m_SubscribFaceDetect) {
//			int chn = 0;//IPC通道一般为0
//			NET_DVR_SUBSCRIBE_REPLY.ByReference sSmartSubscrib = new NET_DVR_SUBSCRIBE_REPLY.ByReference();
//			byte[] sb = m_serverAddressVFD.getBytes();
//			Pointer pNativeData = new Memory(sb.length); 
//			pNativeData.write(0, sb, 0, sb.length);		
//			IntByReference dwResult = new IntByReference();
//			boolean ret = DeviceSdk.INSTANCE.NET_SDK_UnSmartSubscrib(loginId, 1, chn, pNativeData, dwResult);
//			if(ret) {
//				m_SubscribFaceMatch = false;
//				System.out.println("取消订阅报警成功");
//			}
//			// 释放内存
//					long peer = Pointer.nativeValue(pNativeData);
//					Native.free(peer);// 手动释放内存
//					Pointer.nativeValue(pNativeData, 0);
		}
		
			
	}
	//@Test
	public void setSDKMessageCallBack() throws Throwable {

		if(loginId == null||loginId.intValue() < 1) {
			try {
				A();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
//		if(!m_SubscribFaceMatch) {
//			SubscribAlarm();
//		}
		FaceAlarmCB = new SUBSCRIBE_CALLBACK_IMPL();
        // TODO 设置智能分析事件上报回调
        DeviceSdk.INSTANCE.NET_SDK_SetSubscribCallBack(FaceAlarmCB, null);
		 Scanner s = new Scanner(System.in);
	     while (s.hasNext()){
	         if(s.next().equals("q")){
	             break;
	         }
	     }    
	}
	/**
	 * 
	 * @author 8590
	 *
	 */
	//@Test
	public void DevSupport() {
		if(loginId == null||loginId.intValue() < 1) {
			try {
				A();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		NET_SDK_DEV_SUPPORT.ByReference nsds = new NET_SDK_DEV_SUPPORT.ByReference();
		

		boolean ret = DeviceSdk.INSTANCE.NET_SDK_GetDeviceSupportFunction(loginId, nsds);
		if(ret) {						
			int index = devIntelist.supportThermometry.ordinal();
			System.out.println( (nsds.support  & (1<<index)) >> index);
			
		}		
	}
	public enum devIntelist{
		supportThermometry,//口罩跟体温
        supportVfd,//人脸检测
        supportVfdMatch,//人脸比对
        supportThermal,////热成像
        supportPassLine,//过线统计
	}
	public enum intelist { 
		intelist_enable,//是否包含智能能力集列表
        intelist_Perimeter,//区域入侵
        intelist_Tripwire,//绊线侦测
        intelist_Osc,//物品看护
        intelist_Avd,//异常侦测
        intelist_Cpc,//人流量统计
        intelist_Cdd,//人群密度检测
        intelist_Ipd,//人员入侵侦测
        intelist_Vfd,//人脸抓拍
        intelist_Vfd_Match,//人脸比对
        intelist_Vehice,//车牌检测
        intelist_AoiEntry,//进入区域
        intelist_AoiLeave,//离开区域
        intelist_PassLineCount,//过线统计
        intelist_Vfd_Detect,//人脸侦测
        intelist_Traffic,//流量统计
        intelist_Thermal, //热成像测温
		};
		 /* @author 8590
		 *
		 */
		@Test
		public void capture() {
			if(loginId == null||loginId.intValue() < 1) {
				try {
					A();
				} catch (Throwable e) {
					e.printStackTrace();
				}
			}
			Pointer pNativeData = new Memory(1024 * 1024); 
			IntByReference lpBytesReturned = new IntByReference();
			
			boolean ret = DeviceSdk.INSTANCE.NET_SDK_CaptureJpeg(loginId, 0,0,pNativeData,1024 * 1024,lpBytesReturned);
			if(ret) {
				System.out.println("NET_SDK_CaptureJpeg：" + ret);
				byte[] data = pNativeData.getByteArray(0, lpBytesReturned.getValue()); 
				
				File srcPic = new File( "D:\\123.jpg");//
				try {
					srcPic.createNewFile();
					CommonFunctions.writeFileByBytes("D:\\123.jpg",data,false);//数据写入文件中
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			// 释放内存
			long peer = Pointer.nativeValue(pNativeData);
			Native.free(peer);// 手动释放内存
			Pointer.nativeValue(pNativeData, 0);
			
		}
    
}
