package ru.yandex.direct.http.smart.core;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.ParametersAreNonnullByDefault;

import io.netty.handler.codec.http.HttpHeaders;
import org.asynchttpclient.Param;
import org.asynchttpclient.Request;
import org.asynchttpclient.RequestBuilder;
import org.asynchttpclient.uri.Uri;

@ParametersAreNonnullByDefault
public class SmartRequestBuilder extends RequestBuilder {
    private String relativeUrl;
    private Long requestId = 0L;
    protected List<Param> partibleQueryParams = new ArrayList<>();
    protected List<byte[]> partibleBodyParams = new ArrayList<>();

    public SmartRequestBuilder setRelativeUrl(String relativeUrl) {
        this.relativeUrl = relativeUrl;
        return this;
    }

    public SmartRequestBuilder setRequestId(Long requestId) {
        this.requestId = requestId;
        return this;
    }

    public Long getRequestId() {
        return requestId;
    }

    public void addPathParam(String name, String value) {
        if (relativeUrl == null) {
            throw new AssertionError();
        }
        relativeUrl = relativeUrl.replace("{" + name + "}", value);
    }

    public void addPartibleQueryParam(String name, String value) {
        partibleQueryParams.add(new Param(name, value));
    }

    protected List<Param> getQueryParams() {
        return queryParams;
    }

    public void addPartibleBodyParam(byte[] bytes) {
        partibleBodyParams.add(bytes);
    }

    public List<byte[]> getPartibleBodyParams() {
        return partibleBodyParams;
    }

    public HttpHeaders getHeaders() {
        return headers;
    }

    @Override
    public Request build() {
        String path = Paths.get(uri.getPath(), relativeUrl).toString();
        if (relativeUrl.length() > 1 && relativeUrl.endsWith("/")) {
            path = path + "/";
        }
        Uri savedUri = uri;
        try {
            setUri(Uri.create(uri, path));
            return super.build();
        } finally {
            setUri(savedUri);
        }
    }
}
