package com.slack.api.util.http.listener;

import lombok.extern.slf4j.Slf4j;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

import java.io.IOException;

/**
 * An HTTP response listener that prints the details of request/response mainly for debugging purposes.
 */
@Slf4j
public class DetailedLoggingListener extends HttpResponseListener {

    @Override
    public void accept(State state) {
        if (log.isDebugEnabled()) {
            Response response = state.getResponse();
            String body = state.getParsedResponseBody();

            Buffer requestBody = new Buffer();
            RequestBody requestBodyObj = response.request().body();
            try {
                if (requestBodyObj != null) {
                    requestBodyObj.writeTo(requestBody);
                }
            } catch (IOException e) {
                log.error("Failed to read the request body because {}", e.getMessage(), e);
            }

            String textRequestBody = null;
            try {
                textRequestBody = requestBody.buffer().readUtf8();
            } catch (Exception e) {
                log.debug("Failed to read request body because {}, error: {}", e.getMessage(), e.getClass().getCanonicalName());
            }

            Long contentLength = null;
            try {
                contentLength = requestBodyObj != null ? requestBodyObj.contentLength() : 0;
            } catch (IOException e) {
                log.error("Failed to read the content length because {}", e.getMessage(), e);
            }

            log.debug("\n[Request URL]\n{} {}\n" +
                            "[Specified Request Headers]\n{}" +
                            "[Request Body]\n{}\n\n" +
                            "Content-Type: {}\n" +
                            "Content Length: {}\n" +
                            "\n" +
                            "[Response Status]\n{} {}\n" +
                            "[Response Headers]\n{}" +
                            "[Response Body]\n{}\n",
                    response.request().method(),
                    response.request().url(),
                    response.request().headers(),
                    textRequestBody,
                    requestBodyObj != null ? requestBodyObj.contentType() : null,
                    contentLength,
                    response.code(),
                    response.message(),
                    response.headers(),
                    body);
        }
    }
}

@@ -70,16 +70,40 @@
 .Slf4j;%0A
+import okhttp3.Headers;%0A
 import o
@@ -122,16 +122,16 @@
 stBody;%0A
-
 import o
@@ -195,16 +195,144 @@
 ception;
+%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.Locale;%0A%0Aimport static java.util.stream.Collectors.joining;
 %0A%0A/**%0A *
@@ -1708,32 +1708,719 @@
 %0A            %7D%0A%0A
+            Headers originalRequestHeaders = response.request().headers();%0A            List%3CString%3E requestHeaders = new ArrayList%3C%3E();%0A            for (String headerName : originalRequestHeaders.names()) %7B%0A                if (headerName.toLowerCase(Locale.ENGLISH).equals(%22authorization%22)%0A                        && !state.getConfig().isLibraryMaintainerMode()) %7B%0A                    requestHeaders.add(headerName + %22: (redacted)%22);%0A                %7D else %7B%0A                    requestHeaders.add(headerName + %22: %22 + originalRequestHeaders.get(headerName));%0A                %7D%0A            %7D%0A            String requestHeaderLines = requestHeaders.stream().collect(joining(%22%5Cn%22)) + %22%5Cn%22;%0A%0A
             log.
@@ -2998,36 +2998,26 @@
     
-response.
 request
-().h
+H
 eader
-s()
+Lines
 ,%0A  

Redact authorization header from debug logging outputs