package com.heyu.api.controller.doc;

import com.heyu.api.baidu.handle.doc.BForgeryDetectionHandle;
import com.heyu.api.baidu.request.doc.BForgeryDetectionRequest;
import com.heyu.api.baidu.response.doc.BForgeryDetectionResp;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.request.doc.ForgeryDetectionRequest;
import com.heyu.api.resp.doc.ForgeryDetectionResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 图片篡改检测
 *
 * 基于深度神经网络与跨模态分析技术，精准检测伪造图像，
 * 支持返回图像篡改检测结果及伪造区域坐标；
 * 支持对图像中的伪造区域以热力图形式进行可视化返回。
 *
 * 百度文档：https://cloud.baidu.com/doc/OCR/s/kmfdnccok
 */
@Slf4j
@RestController
@RequestMapping("/doc")
@NotIntercept
public class ForgeryDetectionController {

    @Autowired
    private BForgeryDetectionHandle bForgeryDetectionHandle;

    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @PostMapping("/forgeryDetection")
    public R<ForgeryDetectionResp> forgeryDetection(@RequestBody ForgeryDetectionRequest request) {
        long start = System.currentTimeMillis();

        BForgeryDetectionRequest bRequest = toBaiduRequest(request);

        ApiR<BForgeryDetectionResp> bR = bForgeryDetectionHandle.handle(bRequest);
        if (!bR.isSuccess()) {
            log.info("图片篡改检测-失败, error:{}, 耗时:{}ms", bR.getErrorMsg(), System.currentTimeMillis() - start);
            return R.error(bR.getErrorMsg());
        }

        BForgeryDetectionResp bResp = bR.getData();
        if (bResp.getResult() == null) {
            log.info("图片篡改检测-结果为空, 耗时:{}ms", System.currentTimeMillis() - start);
            return R.error("图片篡改检测结果为空");
        }

        ForgeryDetectionResp resp = toResp(bResp);

        log.info("图片篡改检测-完成, 耗时:{}ms", System.currentTimeMillis() - start);
        return R.ok().setData(resp);
    }

    private BForgeryDetectionRequest toBaiduRequest(ForgeryDetectionRequest request) {
        BForgeryDetectionRequest bRequest = new BForgeryDetectionRequest();
        if (request == null) {
            return bRequest;
        }
        bRequest.setImageBase64(request.getImageBase64());
        bRequest.setImageUrl(request.getImageUrl());
        bRequest.setDetectProportion(request.getDetectProportion());
        bRequest.setDetectThreshold(request.getDetectThreshold());
        bRequest.setReturnHeatmap(request.getReturnHeatmap());
        bRequest.setRestrictProbability(request.getRestrictProbability());
        return bRequest;
    }

    private ForgeryDetectionResp toResp(BForgeryDetectionResp bResp) {
        ForgeryDetectionResp resp = new ForgeryDetectionResp();
        BForgeryDetectionResp.ResultDTO result = bResp.getResult();

        resp.setDetectionResult(result.getDetectionResult());
        resp.setTamperedProportion(result.getTamperedProportion());
        resp.setHeatmap(result.getHeatmap());

        if (result.getTamperedLocation() != null) {
            List<ForgeryDetectionResp.TamperedLocation> locations = new ArrayList<>();
            for (BForgeryDetectionResp.TamperedLocationDTO dto : result.getTamperedLocation()) {
                ForgeryDetectionResp.TamperedLocation location = new ForgeryDetectionResp.TamperedLocation();
                location.setLeft(dto.getLeft());
                location.setTop(dto.getTop());
                location.setWidth(dto.getWidth());
                location.setHeight(dto.getHeight());
                location.setProbability(dto.getProbability());
                locations.add(location);
            }
            resp.setTamperedLocation(locations);
        }

        return resp;
    }
}
