package com.qmth.boot.core.retrofit.interceptor;

import com.qmth.boot.core.retrofit.interfaces.SignatureProvider;
import com.qmth.boot.core.retrofit.utils.SignatureInfo;
import com.qmth.boot.tools.signature.SignatureEntity;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * 签名构造器，符合开发框架通用鉴权标准
 */
public class SignatureInterceptor implements Interceptor {

    private static final Logger log = LoggerFactory.getLogger(SignatureInterceptor.class);

    private static final String BASE_URL = "base_url";

    private static final String HEADER_KEY_AUTHORIZATION = "authorization";

    private static final String HEADER_KEY_TIME = "time";

    private SignatureProvider provider;

    public SignatureInterceptor(SignatureProvider provider) {
        this.provider = provider;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        String path = request.url().uri().getPath();
        String queryParams = request.url().query();
        queryParams = queryParams != null ? "?" + queryParams : "";

        Request.Builder builder = request.newBuilder();
        String baseUrl = request.header(BASE_URL);
        if (StringUtils.isNotBlank(baseUrl)) {
            log.debug("oldUrl:{} newUrl:{}{}{}", request.url(), baseUrl, path, queryParams);
            builder.url(baseUrl + path + queryParams);
        }

        SignatureProvider provider = getSignatureInfo(request);
        if (provider == null) {
            provider = this.provider;
        }
        if (provider != null) {
            long time = System.currentTimeMillis();
            String signature = SignatureEntity.build(provider.getType(), request.method(), path, time,
                    provider.getIdentity(), provider.getSecret());
            builder.removeHeader(HEADER_KEY_TIME).removeHeader(HEADER_KEY_AUTHORIZATION)
                    .addHeader(HEADER_KEY_TIME, String.valueOf(time)).addHeader(HEADER_KEY_AUTHORIZATION, signature);
        }

        if (StringUtils.isNotBlank(baseUrl) || provider != null) {
            return chain.proceed(builder.build());
        } else {
            return chain.proceed(request);
        }
    }

    private SignatureInfo getSignatureInfo(Request request) {
        try {
            return request.tag(SignatureInfo.class);
        } catch (Exception e) {
            return null;
        }
    }

}
