package io.corbel.resources.rem.request.builder;

import io.corbel.lib.token.TokenInfo;
import io.corbel.resources.rem.request.RequestParameters;
import io.corbel.resources.rem.request.RequestParametersImpl;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;

import org.springframework.http.MediaType;

/**
 * @author Rubén Carrasco
 *
 */
public class RequestParametersBuilder<E> {

    private E apiParameters;
    private TokenInfo tokenInfo;
    private List<MediaType> acceptedMediaTypes;
    private MultivaluedMap<String, String> params;
    private Long contentLength;
    private MultivaluedMap<String, String> headers;

    public RequestParametersBuilder() {}

    public RequestParametersBuilder(RequestParameters<E> parameters) {
        this.apiParameters = parameters.getOptionalApiParameters().map(apiParameters -> apiParameters).orElse(null);
        this.tokenInfo = parameters.getTokenInfo();
        this.acceptedMediaTypes = parameters.getAcceptedMediaTypes();
        this.params = parameters.getParams();
        this.contentLength = parameters.getContentLength();
        this.headers = parameters.getHeaders();
    }

    public RequestParameters<E> build() {
        return new RequestParametersImpl<E>(apiParameters, tokenInfo, acceptedMediaTypes, contentLength, params, headers);
    }

    public RequestParametersBuilder<E> apiParameters(E apiParameters) {
        this.apiParameters = apiParameters;
        return this;
    }

    public RequestParametersBuilder<E> tokenInfo(TokenInfo tokenInfo) {
        this.tokenInfo = tokenInfo;
        return this;
    }

    public RequestParametersBuilder<E> acceptedMediaTypes(List<MediaType> acceptedMediaTypes) {
        this.acceptedMediaTypes = acceptedMediaTypes;
        return this;
    }

    public RequestParametersBuilder<E> acceptedMediaType(MediaType mediaType) {
        if (acceptedMediaTypes == null) {
            acceptedMediaTypes = new ArrayList<>();
        }
        acceptedMediaTypes.add(mediaType);
        return this;
    }

    public RequestParametersBuilder<E> params(MultivaluedMap<String, String> params) {
        this.params = params;
        return this;
    }

    public RequestParametersBuilder<E> param(String key, String value) {
        if (params == null) {
            params = new MultivaluedHashMap<>();
        }
        params.add(key, value);
        return this;
    }

    public RequestParametersBuilder<E> contentLength(Long contentLength) {
        this.contentLength = contentLength;
        return this;
    }

    public RequestParametersBuilder<E> headers(MultivaluedMap<String, String> headers) {
        this.headers = headers;
        return this;
    }

    public RequestParametersBuilder<E> header(String key, String value) {
        if (headers == null) {
            headers = new MultivaluedHashMap<>();
        }
        headers.add(key, value);
        return this;
    }
}

@@ -1066,38 +1066,31 @@
 ();%0A        
-this.
 params
- = 
+(
 parameters.g
@@ -1099,16 +1099,17 @@
 Params()
+)
 ;%0A      
@@ -1170,31 +1170,24 @@
         
-this.
 headers
- = 
+(
 paramete
@@ -1201,16 +1201,17 @@
 eaders()
+)
 ;%0A    %7D%0A
@@ -2205,22 +2205,102 @@
 arams = 
-params
+new MultivaluedHashMap%3C%3E();%0A        params.forEach((k, v) -%3E this.params.addAll(k, v))
 ;%0A      
@@ -2802,23 +2802,104 @@
 aders = 
-headers
+new MultivaluedHashMap%3C%3E();%0A        headers.forEach((k, v) -%3E this.headers.addAll(k, v))
 ;%0A      

Change how multivaluedmaps are built to avoid using an immutable map