package ru.yandex.webmaster3.core.nanny;

import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.web.util.UriComponentsBuilder;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.nanny.alemate.NannyTaskgroupInfo;
import ru.yandex.webmaster3.core.nanny.alemate.NannyTaskgroupStatusEnum;
import ru.yandex.webmaster3.core.nanny.internal.NannyJsonUtil;
import ru.yandex.webmaster3.core.util.URLEncodeUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author avhaliullin
 */
public class NannyListTaskgroupsQuery extends NannyQuery<List<NannyTaskgroupInfo>> {
    private final String filterString;
    private final int limit;

    private NannyListTaskgroupsQuery(String filterString, int limit) {
        this.filterString = filterString;
        this.limit = limit;
    }

    @Override
    protected HttpUriRequest makeRequest(UriComponentsBuilder uriBuilder) {
        uriBuilder
                .path("v1/alemate/task_groups/");
        if (filterString != null) {
            uriBuilder.queryParam("filter", URLEncodeUtil.urlEncode(filterString));
        }
        uriBuilder.queryParam("limit", limit);

        return new HttpGet(uriBuilder.build(true).toUri());
    }

    @Override
    protected List<NannyTaskgroupInfo> parseResult(CloseableHttpResponse response) throws IOException {
        if (response.getStatusLine().getStatusCode() != 200) {
            String body = IOUtils.toString(response.getEntity().getContent());
            throw new WebmasterException(
                    "Failed to list nanny taskgroups; nanny returned status " +
                            response.getStatusLine().getStatusCode() + ", response: " + body,
                    new WebmasterErrorResponse.NannyErrorResponse(getClass())
            );
        }
        return NannyJsonUtil.OM.readValue(response.getEntity().getContent(), new TypeReference<List<NannyTaskgroupInfo>>() {
        });
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    private static class Filter {
        private NannyTaskgroupStatusEnum state;
        private String description;
        private String queue;
    }

    public static class Builder {
        private final Filter filter = new Filter();
        private int limit = 10;

        public Builder filterState(NannyTaskgroupStatusEnum state) {
            filter.state = state;
            return this;
        }

        public Builder filterDescription(String description) {
            filter.description = description;
            return this;
        }

        public Builder filterQueue(String queue) {
            filter.queue = queue;
            return this;
        }

        public Builder limit(int limit) {
            this.limit = limit;
            return this;
        }

        public NannyListTaskgroupsQuery build() {
            List<String> filterParts = new ArrayList<>(3);
            if (filter.state != null) {
                filterParts.add("status=" + filter.state);
            }
            if (filter.queue != null) {
                filterParts.add("queue=" + filter.queue);
            }
            if (filter.description != null) {
                filterParts.add("desc=" + filter.description);
            }
            String filterString = filterParts.isEmpty() ? null : String.join("&", filterParts);
            return new NannyListTaskgroupsQuery(filterString, limit);
        }
    }
}
