package io.qameta.allure.restassured;

import io.qameta.allure.attachment.DefaultAttachmentProcessor;
import io.qameta.allure.attachment.FreemarkerAttachmentRenderer;
import io.qameta.allure.attachment.http.HttpRequestAttachment;
import io.qameta.allure.attachment.http.HttpResponseAttachment;
import io.restassured.filter.FilterContext;
import io.restassured.filter.OrderedFilter;
import io.restassured.internal.NameAndValue;
import io.restassured.internal.support.Prettifier;
import io.restassured.response.Response;
import io.restassured.specification.FilterableRequestSpecification;
import io.restassured.specification.FilterableResponseSpecification;

import java.util.HashMap;
import java.util.Map;

import static io.qameta.allure.attachment.http.HttpRequestAttachment.Builder.create;
import static io.qameta.allure.attachment.http.HttpResponseAttachment.Builder.create;

/**
 * Allure logger filter for Rest-assured.
 */
public class AllureRestAssured implements OrderedFilter {

    @Override
    public Response filter(final FilterableRequestSpecification requestSpec,
                           final FilterableResponseSpecification responseSpec,
                           final FilterContext filterContext) {
        final Prettifier prettifier = new Prettifier();

        final HttpRequestAttachment requestAttachment = create("Request", requestSpec.getURI())
                .withBody(prettifier.getPrettifiedBodyIfPossible(requestSpec))
                .withMethod(requestSpec.getMethod())
                .withHeaders(toMapConverter(requestSpec.getHeaders()))
                .withCookies(toMapConverter(requestSpec.getCookies()))
                .build();

        new DefaultAttachmentProcessor().addAttachment(
                requestAttachment,
                new FreemarkerAttachmentRenderer("http-request.ftl")
        );

        final Response response = filterContext.next(requestSpec, responseSpec);
        final HttpResponseAttachment responseAttachment = create(response.getStatusLine())
                .withResponseCode(response.getStatusCode())
                .withHeaders(toMapConverter(response.getHeaders()))
                .withBody(prettifier.getPrettifiedBodyIfPossible(response, response.getBody()))
                .build();

        new DefaultAttachmentProcessor().addAttachment(
                responseAttachment,
                new FreemarkerAttachmentRenderer("http-response.ftl")
        );

        return response;
    }

    private static Map<String, String> toMapConverter(final Iterable<? extends NameAndValue> items) {
        final Map<String, String> result = new HashMap<>();
        items.forEach(h -> result.put(h.getName(), h.getValue()));
        return result;
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}

@@ -697,16 +697,42 @@
 til.Map;
+%0Aimport java.util.Objects;
 %0A%0Aimport
@@ -1293,24 +1293,25 @@
 ttifier();%0A%0A
+%0A
         fina
@@ -1333,16 +1333,24 @@
 tachment
+.Builder
  request
@@ -1351,32 +1351,39 @@
 equestAttachment
+Builder
  = create(%22Reque
@@ -1413,87 +1413,8 @@
 ())%0A
-                .withBody(prettifier.getPrettifiedBodyIfPossible(requestSpec))%0A
     
@@ -1599,24 +1599,26 @@
 tCookies()))
+;%0A
 %0A           
@@ -1610,32 +1610,261 @@
 );%0A%0A        
-        
+if (Objects.nonNull(requestSpec.getBody())) %7B%0A            requestAttachmentBuilder.withBody(prettifier.getPrettifiedBodyIfPossible(requestSpec));%0A        %7D%0A%0A        final HttpRequestAttachment requestAttachment = requestAttachmentBuilder
 .build();%0A%0A 

allow empty body for rest-assured requests (fixes #125, via #142)