package com.api.test;

import com.alibaba.fastjson.JSONObject;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.util.concurrent.TimeUnit;

/**
 * 图片篡改检测 - 集成测试
 * 直接调用百度 API，验证接口连通性和返回结构
 */
public class TestForgeryDetection {

    private static final String API_KEY = "zs9oN4gSuoS3eK8dVJg6jyKh";
    private static final String SECRET_KEY = "uHIRXkj6rbW1eXy8eRVCeP1e3cRQKXay";
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();

    public static void main(String[] args) throws Exception {
        // 1. 获取 access_token
        String accessToken = getAccessToken();
        System.out.println("access_token: " + accessToken.substring(0, 20) + "...");

        // 2. 下载图片并转为 base64
        // 直接下载图片并转base64，避免文件IO问题
        String imageUrl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
        System.out.println("\n下载图片: " + imageUrl);
        String imageBase64 = downloadImageAsBase64(imageUrl);
        System.out.println("图片base64长度: " + imageBase64.length());
        System.out.println("base64前50字符: " + imageBase64.substring(0, Math.min(50, imageBase64.length())));

        // 测试1: 基础检测（base64方式）
        System.out.println("\n========== 测试1: 基础检测(base64) ==========");
        testBasicBase64(accessToken, imageBase64);

        // 等待避免QPS限制
        Thread.sleep(1000);

        // 测试2: 带置信度检测
        System.out.println("\n========== 测试2: 带置信度检测 ==========");
        testWithProportion(accessToken, imageBase64);

        Thread.sleep(1000);

        // 测试3: 带热力图检测
        System.out.println("\n========== 测试3: 带热力图检测 ==========");
        testWithHeatmap(accessToken, imageBase64);
    }

    private static void testBasicBase64(String accessToken, String imageBase64) throws Exception {
        // 测试不编码直接发送（与现有BaiduBaseHandle一致）
        String body = "image=" + imageBase64;
        String result = callBaiduApiRaw(accessToken, body);
        System.out.println("返回结果:\n" + formatJson(result));
        parseResult(result);
    }

    private static void testWithProportion(String accessToken, String imageBase64) throws Exception {
        String body = "image=" + imageBase64
                + "&detect_proportion=true";
        String result = callBaiduApiRaw(accessToken, body);
        System.out.println("返回结果:\n" + formatJson(result));
        parseResult(result);
    }

    private static void testWithHeatmap(String accessToken, String imageBase64) throws Exception {
        String body = "image=" + imageBase64
                + "&detect_proportion=true"
                + "&return_heatmap=true";
        String result = callBaiduApiRaw(accessToken, body);
        System.out.println("返回结果:\n" + formatJson(result));
        parseResult(result);
    }

    private static String downloadImageAsBase64(String url) throws Exception {
        Request request = new Request.Builder().url(url).build();
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            byte[] bytes = response.body().bytes();
            System.out.println("图片大小: " + bytes.length + " bytes");
            return java.util.Base64.getEncoder().encodeToString(bytes);
        }
    }

    private static String callBaiduApiRaw(String accessToken, String bodyStr) throws Exception {
        java.net.URL url = new java.net.URL("https://aip.baidubce.com/rest/2.0/ocr/v1/forgery_detection?access_token=" + accessToken);
        java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Accept", "application/json");

        byte[] bodyBytes = bodyStr.getBytes("UTF-8");
        conn.setRequestProperty("Content-Length", String.valueOf(bodyBytes.length));
        try (java.io.OutputStream os = conn.getOutputStream()) {
            os.write(bodyBytes);
            os.flush();
        }

        try (java.io.BufferedReader reader = new java.io.BufferedReader(
                new java.io.InputStreamReader(conn.getInputStream(), "UTF-8"))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        }
    }

    private static String readBase64FromFile(String filePath) throws Exception {
        StringBuilder sb = new StringBuilder();
        try (java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        return sb.toString();
    }

    private static void parseResult(String result) {
        JSONObject json = JSONObject.parseObject(result);

        if (json.containsKey("error_code")) {
            System.out.println("API错误: error_code=" + json.getString("error_code")
                    + ", error_msg=" + json.getString("error_msg"));
            return;
        }

        JSONObject resultObj = json.getJSONObject("result");
        if (resultObj == null) {
            System.out.println("result 为空");
            return;
        }

        String detectionResult = resultObj.getString("detection_result");
        System.out.println("检测结果: " + ("fake".equals(detectionResult) ? "有篡改" : "无篡改"));

        Double tamperedProportion = resultObj.getDouble("tampered_proportion");
        if (tamperedProportion != null) {
            System.out.println("篡改置信度: " + tamperedProportion);
        }

        String heatmap = resultObj.getString("heatmap");
        if (heatmap != null) {
            System.out.println("热力图长度: " + heatmap.length() + " 字符");
        }
    }

    private static String getAccessToken() throws Exception {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType,
                "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();

        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            String result = response.body().string();
            JSONObject json = JSONObject.parseObject(result);
            return json.getString("access_token");
        }
    }

    private static String formatJson(String json) {
        try {
            JSONObject obj = JSONObject.parseObject(json);
            // 如果有 heatmap，截断显示
            if (obj.containsKey("result")) {
                JSONObject result = obj.getJSONObject("result");
                if (result != null && result.containsKey("heatmap")) {
                    String heatmap = result.getString("heatmap");
                    if (heatmap != null && heatmap.length() > 50) {
                        result.put("heatmap", heatmap.substring(0, 50) + "...(共" + heatmap.length() + "字符)");
                    }
                }
            }
            return obj.toJSONString();
        } catch (Exception e) {
            return json;
        }
    }
}
