package com.uiui.zyappstore.network.interceptor;

import android.util.Log;


import com.uiui.zyappstore.BuildConfig;
import com.uiui.zyappstore.utils.MD5Util;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import okhttp3.Interceptor;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

/**
 * v1.0 2022-07-15 16:16:52
 */
public class RepeatRequestInterceptor implements Interceptor {
    private static final String TAG = RepeatRequestInterceptor.class.getSimpleName();

    private final ConcurrentHashMap<String, Long> requestIdsMap = new ConcurrentHashMap<>();
    public static final String REPEAT_REQUEST_PROTOCOL = "OKHTTP_REPEAT_REQUEST_PROTOCOL";

    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        ResponseBody responseBody = response.body();

        //会消费请求，导致请求多次
        String content = responseBody.string();
//        Response copy = response.newBuilder().body(responseBody).build();
        ResponseBody copy = ResponseBody.create(responseBody.contentType(), content);
        if (BuildConfig.DEBUG) {
            Log.e(TAG, "请求体返回：| Response: " + request.url() + "\t body: " + content);
        }
        //相同的请求
        String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString() + requestBodyToString(request.body()));
        long time = System.currentTimeMillis();//请求时间
        try {
            if (requestIdsMap.size() > 0 && requestIdsMap.containsKey(requestKey)) {
                log("重复请求:", requestKey, request);
                //下面这行写了不会抛出onerror
//                            chain.call().cancel();
                return new Response.Builder()
                        .protocol(Protocol.get(REPEAT_REQUEST_PROTOCOL))
                        .request(request) //multi thread
                        .build();
            }
            requestIdsMap.put(requestKey, time);
            log("注册请求:", requestKey, request);
//                            RepeatRequestInterceptor.Builder builder = request.newBuilder();
//                        builder.addHeader("header", jsonObject.toString());
            return response.newBuilder().body(copy).build();
        } catch (IOException e) {
            Log.e(TAG, "intercept: " + e.getMessage());
            throw e;
        } finally {
            if (requestIdsMap.containsKey(requestKey) && requestIdsMap.containsValue(time)) {//请求任务完成删除map中的数据
                requestIdsMap.remove(requestKey);
                log("移除请求:", requestKey, request);
            }
        }
    }

    private void log(String action, String requestKey, Request request) {
        if (BuildConfig.DEBUG) {
            Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method() + " --- " + " URL = " + request.url().encodedPath() + "\t" + bodyToString(request));
        } else {
            Log.e("REPEAT-REQUEST", action + requestKey + " Method @" + request.method());
        }
    }

    private static String bodyToString(final Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            if (buffer.size() > 4096) {
                return "-too long";
            }
            return buffer.readUtf8();
        } catch (Exception e) {
            return "-";
        }
    }

    private static String requestBodyToString(RequestBody body) {
        try {
            final Buffer buffer = new Buffer();
            body.writeTo(buffer);
            if (buffer.size() > 4096) {
                return "-too long";
            }
            return buffer.readUtf8();
        } catch (Exception e) {
            return "-";
        }
    }
}
