package com.zd.face.handle;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.arcsoft.face.ActiveFileInfo;
import com.arcsoft.face.EngineConfiguration;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.FunctionConfiguration;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.DetectOrient;
import com.arcsoft.face.enums.ErrorInfo;
import com.zd.common.core.exception.ServiceException;
import com.zd.face.config.FaceProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.IOException;

/**
 * @Author: zhoupan
 * @Date: 2021/10/12/11:14
 * @Description:
 */
@Service
@EnableConfigurationProperties(FaceProperties.class)
public class FaceEngineFactory {
    Logger logger = LoggerFactory.getLogger(FaceEngineFactory.class);

    @Autowired
    FaceProperties faceProperties;

    @Autowired
    EngineConfiguration getEngineConfiguration;

    //初始化一个图片模式引擎
    public FaceEngine initFaceEngineImage() {
        //初始化IMAGE模式
        return init();
    }

    private FaceEngine init() {
        FaceEngine faceEngine = getFaceEngine();
        int errorCode;
        //初始化引擎
        errorCode = faceEngine.init(getEngineConfiguration);
        if (errorCode != ErrorInfo.MOK.getValue()) {
            logger.error("初始化引擎失败:errorCode:{},", errorCode);
            throw new ServiceException("初始化引擎失败!");
        }
        return faceEngine;
    }

    /**
     * 获取激活信息
     * @param faceEngine
     * @return
     */
    private void getActiveInfo(FaceEngine faceEngine) {
        int errorCode;
        ActiveFileInfo activeFileInfo = new ActiveFileInfo();
        errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            logger.error("获取激活文件信息失败:errorCode:{},", errorCode);
            throw new ServiceException("获取激活文件信息失败");
        }
    }

    public String getPath() throws IOException {
        FileSystemResource resource = new FileSystemResource("../");
        String canonicalPath  = resource.getFile().getCanonicalPath();
        if(StrUtil.isNotBlank(faceProperties.getLib_folder()))
        {
            canonicalPath =canonicalPath+File.separator+faceProperties.getLib_folder();
        }
        return canonicalPath;
    }

    public void activation(FaceEngine faceEngine) {

        //
        String key ="";
        String os =  System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            key=faceProperties.getWinKey();
        }else
        {
            key=faceProperties.getLinuxKey();

        }
        logger.info("配置信息打印：" + faceProperties.getAppId() + ", " + key);
        int errorCode = faceEngine.activeOnline(faceProperties.getAppId(), key);
        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            logger.error("引擎激活失败:errorCode:{},", errorCode);
            throw new ServiceException("引擎激活失败");
        }
    }

    /**
     * 在线激活
     */
    public void activeOnline()
    {
        FaceEngine faceEngine = getFaceEngine();
        if (faceEngine == null) return;
        activation(faceEngine);
        getActiveInfo(faceEngine);
    }

    private FaceEngine getFaceEngine() {
        FaceEngine faceEngine =null;
        //默认放在资源文件下

        String canonicalPath = null;
        try {
            //FaceEngine 里加载sdk的方法已经写死了，没办法从打的jar文件中正确获取文件，
            // 里面用的System.load方法，没办法通过路径加载jar文件中的文件
            //所以这里只能把lib文件放在jar文件外部
            canonicalPath = getPath();
            logger.info("获取lib文件路径！:{}",canonicalPath);
            faceEngine =new FaceEngine(canonicalPath);
        } catch (IOException e) {
            logger.error("lib文件路径获取失败，引擎初始化中断，请正确配置后激活！当前读取路径：{}",canonicalPath);
            throw new ServiceException("lib文件加载失败！");
        }
        return faceEngine;
    }


    /**
     * 注入IMAGE 模式配置
     * @return
     */
    @Bean
    public EngineConfiguration getEngineConfiguration() {
        //引擎配置
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        //检测模式
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        //人脸检测角度，根据官网说明按当前一体机使用情况 0角度检测 最佳
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(32);
        //人脸识别时一般都需要supportFaceDetect和supportFaceRecognition这两个属性。
        //需要防止纸张、屏幕等攻击可以传入supportLiveness和supportIRLiveness，RGB和IR活体检测根据用户的摄像头类型及实际的业务需求来决定如何选择。
        //功能配置
        FunctionConfiguration functionConfiguration = new FunctionConfiguration();
        //是否支持年龄检测功能
        functionConfiguration.setSupportAge(false);
        //是否支持3D检测功能
        functionConfiguration.setSupportFace3dAngle(false);
        //是否支持人脸检测功能
        functionConfiguration.setSupportFaceDetect(true);
        //是否支持人脸识别功能
        functionConfiguration.setSupportFaceRecognition(true);
        //是否支持性别检测功能
        functionConfiguration.setSupportGender(false);
        //是否支持RGB活体检测功能
        functionConfiguration.setSupportLiveness(true);
        //是否支持IR活体检测功能
        functionConfiguration.setSupportIRLiveness(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);
        return engineConfiguration;
    }

}
