package unitTest;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

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 netsdk.callback.ACCEPT_REGISTER_CALLBACK;
import netsdk.callback.DRAW_FUN_CALLBACK;
import netsdk.callback.EXCEPTION_CALLBACK;
import netsdk.callback.LIVE_DATA_CALLBACK;
import netsdk.callback.NET_MESSAGE_CALLBACK;
import netsdk.callback.impl.ACCEPT_REGISTER_CALLBACK_IMPL;
import netsdk.callback.impl.DRAW_FUN_CALLBACK_IMPL;
import netsdk.callback.impl.EXCEPTION_CALLBACK_IMPL;
import netsdk.callback.impl.LIVE_DATA_CALLBACK_IMPL;
import netsdk.callback.impl.NET_MESSAGE_CALLBACK_IMPL;
import netsdk.lib.DeviceSdk;
import netsdk.struct.DD_TIME;
import netsdk.struct.LPNET_SDK_CLIENTINFO;
import netsdk.struct.LPNET_SDK_DEVICEINFO;
import netsdk.struct.NET_SDK_CH_DEVICE_STATUS;
import netsdk.struct.NET_SDK_REC_FILE;

public class JunitTest {
	public static ACCEPT_REGISTER_CALLBACK fRegisterCBFun;
	@Test
	public void init() {
		System.out.println("*********************初始化******************************");
		boolean result = DeviceSdk.INSTANCE.NET_SDK_Init();
		System.out.println(result);
	}
	
	@Test
	public void login() {
		try{
			System.out.println("*********************登录******************************");
			LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
				NativeLong result = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.52.102", 9008, "admin", "x", lpDeviceInfo, 0,
					null);
			System.out.println(result);
			System.out.println("localVideoInputNum: " + lpDeviceInfo.localVideoInputNum);
			System.out.println("audioInputNum: " + lpDeviceInfo.audioInputNum);
			System.out.println("sensorInputNum: " + lpDeviceInfo.sensorInputNum);
			System.out.println("sensorOutputNum: " + lpDeviceInfo.sensorOutputNum);
			System.out.println("displayResolutionMask: " + lpDeviceInfo.displayResolutionMask);
			System.out.println("videoOuputNum: " + lpDeviceInfo.videoOuputNum);
			System.out.println("netVideoOutputNum: " + lpDeviceInfo.netVideoOutputNum);
			System.out.println("netVideoInputNum: " + lpDeviceInfo.netVideoInputNum);
			System.out.println("IVSNum: " + lpDeviceInfo.IVSNum);
			System.out.println("presetNumOneCH: " + lpDeviceInfo.presetNumOneCH);
			System.out.println("cruiseNumOneCH: " + lpDeviceInfo.cruiseNumOneCH);
			System.out.println("presetNumOneCruise: " + lpDeviceInfo.presetNumOneCruise);
			System.out.println("trackNumOneCH: " + lpDeviceInfo.trackNumOneCH);
			System.out.println("userNum: " + lpDeviceInfo.userNum);
			System.out.println("netClientNum: " + lpDeviceInfo.netClientNum);
			System.out.println("netFirstStreamNum: " + lpDeviceInfo.netFirstStreamNum);
			System.out.println("deviceType: " + lpDeviceInfo.deviceType);
			System.out.println("doblueStream: " + lpDeviceInfo.doblueStream);
			System.out.println("audioStream: " + lpDeviceInfo.audioStream);
			System.out.println("talkAudio: " + lpDeviceInfo.talkAudio);
			System.out.println("bPasswordCheck: " + lpDeviceInfo.bPasswordCheck);
			System.out.println("defBrightness: " + lpDeviceInfo.defBrightness);
			System.out.println("defContrast: " + lpDeviceInfo.defContrast);
			System.out.println("defSaturation: " + lpDeviceInfo.defSaturation);
			System.out.println("defHue: " + lpDeviceInfo.defHue);
			System.out.println("videoInputNum: " + lpDeviceInfo.videoInputNum);
			System.out.println("deviceID: " + lpDeviceInfo.deviceID);
			System.out.println("videoFormat: " + lpDeviceInfo.videoFormat);
			System.out.println("function: " + lpDeviceInfo.function);
			System.out.println("deviceIP: " + lpDeviceInfo.deviceIP);
			System.out.println("deviceMAC: " + lpDeviceInfo.deviceMAC);
			System.out.println("devicePort: " + lpDeviceInfo.devicePort);
			System.out.println("buildDate: " + lpDeviceInfo.buildDate);
			System.out.println("buildTime: " + lpDeviceInfo.buildTime);
			System.out.println("deviceName: " + new String(lpDeviceInfo.deviceName, "utf-8"));
			System.out.println("firmwareVersion: " + new String(lpDeviceInfo.firmwareVersion, "utf-8"));
			System.out.println("kernelVersion: " + new String(lpDeviceInfo.kernelVersion, "utf-8"));
			System.out.println("hardwareVersion: " + new String(lpDeviceInfo.hardwareVersion, "utf-8"));
			System.out.println("MCUVersion: " + new String(lpDeviceInfo.MCUVersion, "utf-8"));
			System.out.println("firmwareVersionEx: " + new String(lpDeviceInfo.firmwareVersionEx, "utf-8"));
			System.out.println("szSN: " + new String(lpDeviceInfo.szSN, "utf-8"));
			System.out.println("deviceProduct: " + new String(lpDeviceInfo.deviceProduct, "utf-8"));
		}
		catch(Throwable ex){
			System.out.println(ex.getMessage());			
		}
	}
	@Test
	public void logout() {
		System.out.println("*********************退出登录******************************");
		NativeLong userId = new NativeLong(1);
		boolean result = DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
		System.out.println(result);
	}
	
	@Test
	public void cleanUp() {
		System.out.println("*********************退出,释放资源******************************");
		boolean result = DeviceSdk.INSTANCE.NET_SDK_Cleanup();
		System.out.println(result);
	}
	
	
	@Test
	public void setConnectTime() {
		System.out.println("*********************设置连接时间******************************");
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetConnectTime(5000, 3);
		System.out.println(result);
	}
	
	@Test
	public void setReconnect() {
		System.out.println("*********************设置重连******************************");
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetReconnect(5000, true);
		System.out.println(result);
	}
	
	@Test
	public void setRegisterPort() {
		System.out.println("*********************SDK被动接收DVR注册 的本地端口号******************************");
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetRegisterPort(2009,null,0);
		System.out.println(result);
	}
	
	@Test
	public void setRegisterCallback() {
		System.out.println("*********************SDK被动接收DVR注册 的本地端口号  回调******************************");
		fRegisterCBFun = new ACCEPT_REGISTER_CALLBACK_IMPL();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetRegisterCallback(fRegisterCBFun, null);
		System.out.println(result);
	}
	
	@Test
	public void setSDKMessageCallBack() {
		System.out.println("*********************异常消息回调函数******************************");
		EXCEPTION_CALLBACK fExceptionCallBack = new EXCEPTION_CALLBACK_IMPL();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetSDKMessageCallBack(1, null, fExceptionCallBack, null);
		System.out.println(result);
	}
	
	@Test
	public void getLastError() {
		System.out.println("*********************错误查询******************************");
		int result = DeviceSdk.INSTANCE.NET_SDK_GetLastError();
		System.out.println(result);
	}
	
	
	@Test
	public void setDVRMessageCallBack() {
		init();
		System.out.println("*********************登录******************************");
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		NativeLong userId = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.51.147", 6036, "admin", "123456", lpDeviceInfo, 0,null);

		System.out.println("*********************设备报警或状态回调函数******************************");
		NET_MESSAGE_CALLBACK fMessageCallBack = new NET_MESSAGE_CALLBACK_IMPL(); 
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetDVRMessageCallBack(fMessageCallBack, null);
		System.out.println(result);
		
		System.out.println("*********************设备报警回调开启******************************");
		NativeLong result1 = DeviceSdk.INSTANCE.NET_SDK_SetupAlarmChan(userId);
		System.out.println(result1);
		Scanner s = new Scanner(System.in);  
        while (s.hasNext()){  
             if(s.next().equals("q")){  
                 break;  
             }  
        }  
        DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
	}
	
	@Test
	public void setupAlarmChan() {
		System.out.println("*********************设备报警回调开启******************************");
		NativeLong userId = new NativeLong(1);
		NativeLong result = DeviceSdk.INSTANCE.NET_SDK_SetupAlarmChan(userId);
		System.out.println(result);
	}
	
	@Test
	public void closeAlarmChan() {
		System.out.println("*********************设备报警回调关闭******************************");
		NativeLong lAlarmHandle = new NativeLong(1);//NET_SDK_SetupAlarmChan的返回值
		boolean result = DeviceSdk.INSTANCE.NET_SDK_CloseAlarmChan(lAlarmHandle);
		System.out.println(result);
	}
	
	@Test
	public void getAlarmStatus() {
		System.out.println("*********************查询设备报警信息******************************");
		NativeLong userId = new NativeLong(1);
		Pointer lpOutBuffer = Pointer.NULL;
		IntByReference ret = new IntByReference();
		
		boolean result = DeviceSdk.INSTANCE.NET_SDK_GetAlarmStatus(userId, lpOutBuffer, 3000, ret);
		System.out.println(result);
	}
	
	
	@Test
	public void getDeviceInfo() throws Exception {
		System.out.println("*********************查询设备信息******************************");
		NativeLong userId = new NativeLong(1);
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_GetDeviceInfo(userId, lpDeviceInfo);
		System.out.println(result);
		System.out.println(new String(lpDeviceInfo.deviceName, "utf-8"));
	}
	
	@Test
	public void getDeviceTime() {
		System.out.println("*********************查询设备当前时间******************************");
		NativeLong userId = new NativeLong(1);
		DD_TIME.ByReference time = new DD_TIME.ByReference();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_GetDeviceTime(userId, time);
		System.out.println(result);
		System.out.println("当前时间是：" + (time.year + 1900) + "/" + (time.month + 1) + "/" + time.mday);
	}
	
	
	@Test
	public void getDeviceCHStatus() throws Throwable{
		init();
		System.out.println("*********************登录******************************");
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		NativeLong userId = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.51.147", 6036, "admin", "123456", lpDeviceInfo, 0,null);
		int num = lpDeviceInfo.videoInputNum;//通道最大数量
		
		System.out.println("*********************查询设备通道状态******************************");
		NET_SDK_CH_DEVICE_STATUS deviceStatus = new NET_SDK_CH_DEVICE_STATUS();
		int structSize = deviceStatus.size();//结构体大小
		int size = structSize * num;
		NativeLong lBuffSize = new NativeLong(size);
		
		//Pointer pDeviceCHStatus = Pointer.NULL; 
		Pointer pDeviceCHStatus = new Memory(size);  
		Pointer pCHCount = new Memory(4);
		boolean result = DeviceSdk.INSTANCE.NET_SDK_GetDeviceCHStatus(userId, pDeviceCHStatus, lBuffSize, pCHCount);
		int chlNum = pCHCount.getInt(0);
		System.out.println("实际通道数量：" + chlNum);
		//
		List<NET_SDK_CH_DEVICE_STATUS> deviceCHStatusList = new ArrayList<NET_SDK_CH_DEVICE_STATUS>(); 
		for(int i = 0;i < chlNum;i++){
			Pointer p = new Memory(structSize); //自定义指针
			int offset = i * structSize;
			byte[] buf = pDeviceCHStatus.getByteArray(offset,structSize);//读取指定位置，结构体数据长度的数据
			p.write(0, buf, 0, structSize);//写入新的自定义指针中
			NET_SDK_CH_DEVICE_STATUS status = new NET_SDK_CH_DEVICE_STATUS(p);
			System.out.println("通道：" + status.channel+"名称：" + new String(status.name, "utf-8"));
			deviceCHStatusList.add(status);
		}
		
		long peer = Pointer.nativeValue(pDeviceCHStatus);  
		Native.free(peer);//手动释放内存  
		Pointer.nativeValue(pDeviceCHStatus, 0);
		System.out.println(result);
		DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
	}
	
	
	@Test
	public void livePlay() {
		System.out.println("*********************实时预览  回调******************************");
		NativeLong userId = new NativeLong(1);
		LIVE_DATA_CALLBACK fLiveDataCallBack = new LIVE_DATA_CALLBACK_IMPL();
		LPNET_SDK_CLIENTINFO.ByReference lpClientInfo = new LPNET_SDK_CLIENTINFO.ByReference();
		NativeLong result = DeviceSdk.INSTANCE.NET_SDK_LivePlay(userId, lpClientInfo, fLiveDataCallBack, null);
		System.out.println(result);
		System.out.println("lChannel:" + lpClientInfo.lChannel);
	}
	
	
	@Test
	public void stopLivePlay() {
		System.out.println("*********************停止预览******************************");
		NativeLong lLiveHandle = new NativeLong(1);//livePlay的返回值
		boolean result = DeviceSdk.INSTANCE.NET_SDK_StopLivePlay(lLiveHandle);
		System.out.println(result);
	}
	
	@Test
	public void setLiveDataCallBack() {
		System.out.println("*********************设置预览数据回调******************************");
		NativeLong lLiveHandle = new NativeLong(1);//livePlay的返回值
		LIVE_DATA_CALLBACK fLiveDataCallBack = new LIVE_DATA_CALLBACK_IMPL();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_SetLiveDataCallBack(lLiveHandle, fLiveDataCallBack, null);
		System.out.println(result);
	}
	
	
	@Test
	public void findFile() {
		System.out.println("*********************根据文件时间查找录像文件******************************");
		NativeLong userId = new NativeLong(1);
		NativeLong lChannel = new NativeLong(1);
		DD_TIME.ByReference lpStartTime = new DD_TIME.ByReference();
		lpStartTime.year = 118;
		lpStartTime.mday = 4;
		lpStartTime.mday = 1;
		DD_TIME.ByReference lpStopTime = new DD_TIME.ByReference();
		lpStopTime.year = 118;
		lpStopTime.mday = 4;
		lpStopTime.mday = 10;
		NativeLong result = DeviceSdk.INSTANCE.NET_SDK_FindFile(userId, lChannel.intValue(), lpStartTime, lpStopTime);
		System.out.println(result);
	}
	
	
	@Test
	public void findNextFile() {
		System.out.println("*********************逐个获取查找到的文件信息******************************");
		NativeLong lFindHandle = new NativeLong(1);//文件查找句柄，NET_SDK_FindFile()的返回值 
		NET_SDK_REC_FILE.ByReference lpFindData = new NET_SDK_REC_FILE.ByReference();
		int result = DeviceSdk.INSTANCE.NET_SDK_FindNextFile(lFindHandle, lpFindData);
		System.out.println(result);
	}
	
	@Test
	public void findClose() {
		System.out.println("*********************关闭文件查找，释放资源。******************************");
		NativeLong lFindHandle = new NativeLong(1);//文件查找句柄，NET_SDK_FindFile()的返回值 
		boolean result = DeviceSdk.INSTANCE.NET_SDK_FindClose(lFindHandle);
		System.out.println(result);
	}
	
	@Test
	public void getFileByTime() {
		init();
		System.out.println("*********************登录******************************");
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		NativeLong userId = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.51.147", 6036, "admin", "123456", lpDeviceInfo, 0,null);
		
		System.out.println("*********************下载录像文件******************************");
		NativeLong lChannel = new NativeLong(1);
		DD_TIME.ByReference lpStartTime = new DD_TIME.ByReference();
		lpStartTime.year = 2018 - 1900;//2018年
		lpStartTime.month = 5 - 1;//5月
		lpStartTime.mday = 9;//9日
		lpStartTime.hour = 10;//时
		lpStartTime.minute = 31;//分
		lpStartTime.second = 55;//秒
		
		DD_TIME.ByReference lpStopTime = new DD_TIME.ByReference();
		lpStopTime.year = 2018 - 1900;//2018年
		lpStopTime.month = 5 - 1;//5月
		lpStopTime.mday = 9;//9日
		lpStopTime.hour = 10;//时
		lpStopTime.minute = 33;//分
		lpStopTime.second = 23;//秒
		
		NativeLong lFileHandle = DeviceSdk.INSTANCE.NET_SDK_GetFileByTime(userId, lChannel, lpStartTime, lpStopTime, "downloadfile");
		System.out.println(lFileHandle);
		
		System.out.println("*********************下载录像文件进度******************************");

        while (true){  
        	int result = DeviceSdk.INSTANCE.NET_SDK_GetDownloadPos(lFileHandle);
        	 try {
        		 System.out.println(result);
                 Thread.sleep(1000);
             } catch (Exception e) {
                e.printStackTrace();
            }
        	if(result == 100)
        	{
        		System.out.println(result);
        		break;
        	}
        } 
        DeviceSdk.INSTANCE.NET_SDK_StopGetFile(lFileHandle);
        DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
		
		
	}
	
	@Test
	public void getFileByTimeEx() {
		init();
		System.out.println("*********************登录******************************");
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		NativeLong userId = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.51.147", 6036, "admin", "123456", lpDeviceInfo, 0,null);
		
		System.out.println("*********************下载录像文件 Ex******************************");
		NativeLong lChannel = new NativeLong(1);
		DD_TIME.ByReference lpStartTime = new DD_TIME.ByReference();
		lpStartTime.year = 2018 - 1900;//2018年
		lpStartTime.month = 5 - 1;//5月
		lpStartTime.mday = 9;//9日
		lpStartTime.hour = 10;//时
		lpStartTime.minute = 31;//分
		lpStartTime.second = 55;//秒
		
		DD_TIME.ByReference lpStopTime = new DD_TIME.ByReference();
		lpStopTime.year = 2018 - 1900;//2018年
		lpStopTime.month = 5 - 1;//5月
		lpStopTime.mday = 9;//9日
		lpStopTime.hour = 10;//时
		lpStopTime.minute = 33;//分
		lpStopTime.second = 23;//秒
		
		NativeLong lFileHandle = DeviceSdk.INSTANCE.NET_SDK_GetFileByTimeEx(userId, lChannel.intValue(), lpStartTime, lpStopTime, "downloadfileEx",false,false,null,null);
		System.out.println(lFileHandle);
		
		System.out.println("*********************下载录像文件进度******************************");
		
        while (true){  
        	int result = DeviceSdk.INSTANCE.NET_SDK_GetDownloadPos(lFileHandle);
        	 try {
        		 System.out.println(result);
                 Thread.sleep(1000);
             } catch (Exception e) {
                e.printStackTrace();
            }
        	if(result == 100)
        	{
        		System.out.println(result);
        		break;
        	}
        } 
        DeviceSdk.INSTANCE.NET_SDK_StopGetFile(lFileHandle);
        DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
	}
	
	@Test
	public void stopGetFile() {
		System.out.println("*********************停止下载录像文件******************************");
		NativeLong lFileHandle = new NativeLong(1);//句柄，getFileByTime()的返回值 
		boolean result = DeviceSdk.INSTANCE.NET_SDK_StopGetFile(lFileHandle);
		System.out.println(result);
	}
	
	@Test
	public void getDownloadPos() {
		System.out.println("*********************下载录像文件进度******************************");
		NativeLong lFileHandle = new NativeLong(1);//句柄，getFileByTime()的返回值 
		int result = DeviceSdk.INSTANCE.NET_SDK_GetDownloadPos(lFileHandle);
		System.out.println(result);
	}
	
	@Test
	public void faceMatchOperate() throws Throwable {
		init();
		System.out.println("*********************登录******************************");
		LPNET_SDK_DEVICEINFO.ByReference lpDeviceInfo = new LPNET_SDK_DEVICEINFO.ByReference();
		NativeLong userId = DeviceSdk.INSTANCE.NET_SDK_LoginEx("192.168.51.147", 6036, "admin", "123456", lpDeviceInfo, 0,null);
		System.out.println(userId);
		System.out.println("*********************人脸对比相关操作******************************");
		
		int dwInBufferSize = 300;//实际的发送数据的结构体大小
		int dwOutBufferSize = 300;//实际的接受数据的结构体大小
		Pointer lpInBuffer = new Memory(dwInBufferSize);
		Pointer lpOutBuffer = new Memory(dwOutBufferSize); 
		//Pointer lpBytesReturned = new Memory(4); 
		IntByReference lpBytesReturned = new IntByReference();
		boolean result = DeviceSdk.INSTANCE.NET_SDK_FaceMatchOperate(userId,12, lpInBuffer, dwInBufferSize, lpOutBuffer, dwOutBufferSize, lpBytesReturned);
		System.out.println(result);
		
		DeviceSdk.INSTANCE.NET_SDK_Logout(userId);
	}
	
	@Test
	public void registerDrawFun() {
		System.out.println("*********************实时预览或回放时画面叠加字符和图像  回调******************************");
		DRAW_FUN_CALLBACK fDrawFun = new DRAW_FUN_CALLBACK_IMPL();
		NativeLong lLiveHandle = new NativeLong(1);//livePlay的返回值
		boolean result = DeviceSdk.INSTANCE.NET_SDK_RegisterDrawFun(lLiveHandle, fDrawFun, null);
		System.out.println(result);
	}
}
