package com.heyu.api.controller.face;


import com.aliyun.facebody20191230.models.DeepfakeFaceResponse;
import com.aliyun.facebody20191230.models.DeepfakeFaceResponseBody;
import com.heyu.api.alibaba.handle.facebody.ADeepfakeFaceHandle;
import com.heyu.api.alibaba.request.ACommonTextRequest;
import com.heyu.api.alibaba.request.facebody.ADeepfakeFaceRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.request.CommonReq;
import com.heyu.api.request.face.DeepfakeFaceReq;
import com.heyu.api.resp.face.DeepfakeFaceListResp;
import com.heyu.api.resp.face.DeepfakeFaceResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/***
 * https://next.api.aliyun.com/api/facebody/2019-12-30/DeepfakeFace?RegionId=cn-shanghai&tab=DEMO&lang=JAVA
 *
 *换脸鉴别
 *
 * DeepfakeFace
 *
 *
 * 换脸鉴别基于图像算法 AI 技术，实现对图片人脸的真伪进行灵敏检测和深度分析。能力范围支持：
 *
 * 鉴别图片中的人脸是否为 AI 换脸算法所深度合成的假脸。
 * 鉴别图片中的人脸是否为 AI 人脸属性编辑生成类算法所深度合成的假脸。深度伪造技术是指利用深度学习实现图片或视频换脸、人脸编辑生成的技术。
 * 关于该接口功能的示例图如下：
 *
 * 未经算法合成：
 *
 *
 * 应用场景
 * 打击换脸视频网络传播：互联网娱乐性质换脸小程序、APP 应用爆火，换脸鉴别技术可以识别出网络短视频中的伪造视频人脸，杜绝视频换脸造假。
 * 打击互联网 ID 换脸诈骗：深度伪造技术高频使用，假视频与社交网络结合深深影响舆论走向和诱导诈骗。换脸鉴别可识别网上业务办理中的人脸伪造视频，减少网络诈骗。
 * 打击色情娱乐等黑灰产业：互联网的深度伪造合成的色情视频数量巨大，换脸鉴别可以识别此类伪造视频，减少伪造视频人脸色情内容传播，切断色情传播链路。
 * 人脸特征编辑鉴别：真人 ID 版权核验，通过换脸鉴别可以识别出版权素材库中人脸属性编辑生成算法所深度合成的假脸图片素材，杜绝换脸造假，杜绝人脸版权侵权行为。
 *
 *
 * 特色优势
 * 反制 AI 技术滥用：换脸鉴别基于达摩院人脸图像算法和 Deepfake 鉴别技术，提供对图像中的人脸特征进行全方位分析，利用 AI 技术反制换脸、合成脸、人脸特征编辑生成这类 AI 技术的滥用，保护用户合法权益、维护社会公共安全。
 * 领先鉴别技术：基于图片中人像目标的高维度全量特征，换脸鉴别服务涵盖依据视频图像的像素、纹理级别的低阶特征，到具有全局语义的高阶特征，对图像进行全方位、高语义、多层次组合分析，攻防一体式的训练，极大提升合成人脸图片检出率。
 * 准确率高：换脸鉴别结合阿里云多年人脸识别技术能力和大数据安全技术能力，能对视频图像中 AI 换脸、AI 人脸生成等技术进行准确识别判断，对 AI 换脸攻击识别准确率高。
 * 支持单个或多个人脸判断逻辑，可直接调用的 API 接口，服务简单易用，易被集成，兼容性强。
 *
 *
 */
@Slf4j
@RestController
@RequestMapping("/face")
@NotIntercept
public class DeepfakeFaceController extends BaseController {

    @Autowired
    private ADeepfakeFaceHandle aDeepfakeFaceHandle;

    @RequestMapping("/deepfake")
    @CacheResult
    public R deepfake(DeepfakeFaceReq req) {

        ADeepfakeFaceRequest aDeepfakeFaceRequest = new ADeepfakeFaceRequest();

        List<ACommonTextRequest> urls = new ArrayList<>();


        for (CommonReq image : req.getImages()) {
            ACommonTextRequest textRequest = new ACommonTextRequest();
            textRequest.setImageBase64(image.getImageBase64());
            textRequest.setImageUrl(image.getImageUrl());
            urls.add(textRequest);

        }
        aDeepfakeFaceRequest.setUrls(urls);



        List<DeepfakeFaceResp> faces = new ArrayList<>();

        ApiR<DeepfakeFaceResponse> aR = aDeepfakeFaceHandle.handle(aDeepfakeFaceRequest);
        if(aR.isSuccess() && isSuccessStatusCode(aR.getData().getStatusCode())){
            DeepfakeFaceResponseBody responseBody = aR.getData().getBody();
            DeepfakeFaceResponseBody.DeepfakeFaceResponseBodyData responseBodyData = responseBody.getData();
            List<DeepfakeFaceResponseBody.DeepfakeFaceResponseBodyDataElements> elements = responseBodyData.getElements();

            for (DeepfakeFaceResponseBody.DeepfakeFaceResponseBodyDataElements element : elements) {
                DeepfakeFaceResp faceResp = new DeepfakeFaceResp();
                faceResp.setFaceNumber(element.getFaceNumber());
                faceResp.setImageUrl(element.getImageURL());

                List<DeepfakeFaceListResp> faceListResps = new ArrayList<>();

                List<DeepfakeFaceResponseBody.DeepfakeFaceResponseBodyDataElementsResults> results = element.getResults();
                if(CollectionUtils.isNotEmpty(results)){
                    for (DeepfakeFaceResponseBody.DeepfakeFaceResponseBodyDataElementsResults result : results) {

                        DeepfakeFaceListResp resp = new DeepfakeFaceListResp();
                        resp.setConfidence(result.getConfidence());
                        resp.setLabel(result.getLabel());
                        faceListResps.add(resp);
                    }
                }
                faceResp.setDeepfakeFaceListResps(faceListResps);
            }
            return R.ok().setData(faces);
        }
        return R.error();
    }
}
