package com.mortals.xhx.module.hik;

import com.hikvision.artemis.sdk.config.ArtemisConfig;
import com.mortals.xhx.hikdoor.Commom.osSelect;
import com.mortals.xhx.hikdoor.NetSDKDemo.HCNetSDK;
import com.mortals.xhx.module.door.model.DoorEntity;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public abstract class AbstractHikService {

    @Value("${hik.host:}")
    protected String host;

    @Value("${hik.appKey:''}")
    protected String appKey;

    @Value("${hik.appSecret:''}")
    protected String appSecret;

    @Value("${hik.protocol:http://}")
    protected String protocol;

    public String ARTEMIS_PATH = "/artemis";

    protected Map<String, String> path = new HashMap<>(2);

    // int lUserID = -1;//用户句柄
    static int iCharEncodeType = 0;  //设备字符集

    private HCNetSDK hCNetSDK;

    protected HCNetSDK createSDKInstance() {
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strDllPath = "";
                try {
                    //System.setProperty("jna.debug_load", "true");
                    if (osSelect.isWindows())
                        //win系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
                    else if (osSelect.isLinux())
                        //Linux系统加载库路径
                        //  strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
                        strDllPath = "/home/jx/lib/libhcnetsdk.so";
                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);


                    if (osSelect.isLinux()) {
                        HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
                        HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
                        //这里是库的绝对路径，请根据实际情况修改，注意改路径必须有访问权限
                        // String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
                        String strPath1 = "/home/jx/lib/libcrypto.so.1.1";
                        // String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
                        String strPath2 = "/home/jx/lib/libssl.so.1.1";

                        System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
                        ptrByteArray1.write();
                        hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());

                        System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
                        ptrByteArray2.write();
                        hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());

                        //  String strPathCom = System.getProperty("user.dir") + "/lib/";
                        String strPathCom = "/home/jx/lib/";
                        HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
                        System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
                        struComPath.write();
                        hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
                    }

                    /**初始化*/
                    hCNetSDK.NET_DVR_Init();
                    /**加载日志*/
                    boolean i = hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);

                } catch (Exception ex) {
                    log.error("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return hCNetSDK;
                }
            }
        }
        return hCNetSDK;
    }



    /**
     * 加载日志
     */
    protected int login(HCNetSDK hCNetSDK, DoorEntity doorEntity) {
        int lUserID = -1;//用户句柄
        //注册
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
        String m_sDeviceIP = doorEntity.getIp();//设备ip地址
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        String m_sUsername = doorEntity.getUsername();//设备用户名
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        String m_sPassword = doorEntity.getPassword();//设备密码
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = doorEntity.getPort().shortValue(); //sdk端口
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID == -1) {
            log.info("登录失败，错误码为" + hCNetSDK.NET_DVR_GetLastError());
            return lUserID;
        } else {
            log.info("登录成功！");
            m_strDeviceInfo.read();
            iCharEncodeType = m_strDeviceInfo.byCharEncodeType;
            return lUserID;

        }
    }


    /**
     * 登出操作
     */
    public void logout(HCNetSDK hCNetSDK, int lUserID) {
        /**登出和清理，释放SDK资源*/
        if (lUserID >= 0) {
            hCNetSDK.NET_DVR_Logout(lUserID);
        }

    }
    protected ArtemisConfig getArtemisConfig() {
        ArtemisConfig config = new ArtemisConfig();
        config.setHost(host);
        config.setAppKey(appKey);  // 秘钥appkey
        config.setAppSecret(appSecret);// 秘钥appSecret
        return config;
    }

}
