package com.cm.smartgate.pojo.util;

import com.cm.smartgate.config.NetManagementConfig;
import com.cm.smartgate.pojo.dtos.SmartGateDTO;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import netmanager.lib.DataUtils;
import netmanager.lib.PlatUtils;
import netmanager.lib.netmanager.NetEnums;
import netmanager.lib.netmanager.NetLib;
import netmanager.lib.netmanager.NetStructs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * 闸机设备操纵工具类
 * 2020年9月9日16:30:58
 * CBC
 */
@Component
public class NetManagementUtil {

    private static NetManagementConfig netManagementStaticConfig;

    @Autowired
    private NetManagementConfig netManagementConfig;

    @PostConstruct
    public void init() {
        netManagementStaticConfig = netManagementConfig;
    }

    /**
     * 登录闸机设备
     * @return
     */
    public static NativeLong loginDevice(SmartGateDTO smartGateDTO) {
        NetLib instance = (NetLib) Native.loadLibrary(PlatUtils.sdk_plat_getLoadLibrary(netManagementStaticConfig.getConfigPath(), "netmanager"), NetLib.class);
        instance.Net_Init(null, null);
        IntByReference error = null;
        NativeLong loginID = instance.Net_LoginDevice(smartGateDTO.getSmartGateIpAddress(), Integer.valueOf(smartGateDTO.getSmartGatePort()), smartGateDTO.getSmartGateUsername(), smartGateDTO.getSmartGatePassword(), null, error);
        return loginID;
    }

    /**
     * 登出闸机设备
     */
    public static void logoutDevice(NativeLong loginID) {
        NetLib instance = (NetLib) Native.loadLibrary(PlatUtils.sdk_plat_getLoadLibrary(netManagementStaticConfig.getConfigPath(), "netmanager"), NetLib.class);
        instance.Net_Init(null, null);
        instance.Net_LogoutDevice(loginID);
        instance.Net_Exit();
    }

    /**
     * 配置Rtsp
     * @param smartGateDTO
     * @param smartgateConfigRtspSwitch
     * @param smartgateConfigRtspPort
     * @param smartgateConfigRtspMaxConnection
     * @param smartgateConfigRtspStartPort
     * @param smartgateConfigRtspEndPort
     * @throws Exception
     */
    public static void respConfig(SmartGateDTO smartGateDTO, String smartgateConfigRtspSwitch, Integer smartgateConfigRtspPort, Integer smartgateConfigRtspMaxConnection, Integer smartgateConfigRtspStartPort,  Integer smartgateConfigRtspEndPort ) throws Exception {
        NativeLong nativeLong = loginDevice(smartGateDTO);

        IntByReference inBufferSize = new IntByReference(0);
        NetStructs.STU_CFG_NET_RTSP stuCfgNetRtsp = new NetStructs.STU_CFG_NET_RTSP();
        stuCfgNetRtsp.nRtspPort = smartgateConfigRtspPort;
        stuCfgNetRtsp.nMaxConnectNum = smartgateConfigRtspMaxConnection;
        stuCfgNetRtsp.stuRtp.uStartPort = smartgateConfigRtspStartPort;
        stuCfgNetRtsp.stuRtp.uEndPort = smartgateConfigRtspEndPort;
        inBufferSize.setValue(stuCfgNetRtsp.size());
        Pointer ptrInBuffer = DataUtils.sdk_data_createPtr(inBufferSize.getValue());
        DataUtils.sdk_data_structureToPtr(stuCfgNetRtsp, ptrInBuffer, 0);

        NetLib instance = (NetLib) Native.loadLibrary(PlatUtils.sdk_plat_getLoadLibrary(netManagementStaticConfig.getConfigPath(), "netmanager"), NetLib.class);
        boolean bResult = instance.Net_SetDeviceCfg(
                nativeLong,
                NetEnums.EM_DEVICE_CFG_TYPE.DEVICE_CFG_RTSP,
                0,
                ptrInBuffer,
                inBufferSize.getValue(),
                6000);

        if(!bResult) {
            int error = instance.Net_LastError();
            String strError = String.format("配置RTSP设置出现错误, command = %d, errorCode = %d",  NetEnums.EM_DEVICE_CFG_TYPE.DEVICE_CFG_AUTO_MAINTAIN, error);
            System.err.println(strError);
            throw new Exception("RTSP设置保存出错");
        }

        logoutDevice(nativeLong);
    }

    /**
     * 配置自动维护
     * @param smartGateDTO
     * @param smartgateConfigMaintainSwitch
     * @param smartgateConfigWeekend
     * @param smartgateConfigWeekendHour
     * @throws Exception
     */
    public static void maintainConfig(SmartGateDTO smartGateDTO, String smartgateConfigMaintainSwitch, Integer smartgateConfigWeekend, Integer smartgateConfigWeekendHour) throws Exception {
        NativeLong nativeLong = loginDevice(smartGateDTO);

        IntByReference inBufferSize = new IntByReference(0);
        NetStructs.STU_CFG_AUTO_MAINTAIN stuCfgAutoMaintain = new NetStructs.STU_CFG_AUTO_MAINTAIN();
        stuCfgAutoMaintain.bEnable = 0;
        stuCfgAutoMaintain.uWeekDay = smartgateConfigWeekend;
        stuCfgAutoMaintain.uHour = smartgateConfigWeekendHour;
        inBufferSize.setValue(stuCfgAutoMaintain.size());
        Pointer ptrInBuffer = DataUtils.sdk_data_createPtr(inBufferSize.getValue());
        DataUtils.sdk_data_structureToPtr(stuCfgAutoMaintain, ptrInBuffer, 0);

        NetLib instance = (NetLib) Native.loadLibrary(PlatUtils.sdk_plat_getLoadLibrary(netManagementStaticConfig.getConfigPath(), "netmanager"), NetLib.class);
        boolean bResult = instance.Net_SetDeviceCfg(
                nativeLong,
                NetEnums.EM_DEVICE_CFG_TYPE.DEVICE_CFG_AUTO_MAINTAIN,
                0,
                ptrInBuffer,
                inBufferSize.getValue(),
                6000);

        if(!bResult) {
            int error = instance.Net_LastError();
            String strError = String.format("配置自动维护出现错误, command = %d, errorCode = %d",  NetEnums.EM_DEVICE_CFG_TYPE.DEVICE_CFG_AUTO_MAINTAIN, error);
            System.err.println(strError);
            throw new Exception("维护设置保存出错");
        }

        logoutDevice(nativeLong);
    }

    /**
     * 基本配置
     * @param smartGateDTO
     * @param smartgateConfigBasicModeConfiguration
     * @param smartgateConfigModeOfPassage
     * @throws Exception
     */
    public static void baseConfig(SmartGateDTO smartGateDTO, String smartgateConfigBasicModeConfiguration, String smartgateConfigModeOfPassage) throws Exception {
        NativeLong nativeLong = loginDevice(smartGateDTO);

        logoutDevice(nativeLong);
    }

}
