package ru.yandex.qe.dispenser.client.v1.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.cxf.jaxrs.client.WebClient;
import org.jetbrains.annotations.NotNull;

public final class ResourceFilter extends RequestFilter {
    @NotNull
    private final List<ResourceReference> resourceReferences;

    @NotNull
    public static ResourceFilter singleResource(@NotNull final String serviceKey, @NotNull final String resourceKey) {
        return new ResourceFilter(Collections.singletonList(ResourceReference.createFor(serviceKey, resourceKey)));
    }

    public static ResourceFilter.Builder resource(@NotNull final String serviceKey, @NotNull final String resourceKey) {
        return new Builder(ResourceReference.createFor(serviceKey, resourceKey));
    }

    private ResourceFilter(@NotNull final List<ResourceReference> resourceReferences) {
        this.resourceReferences = resourceReferences;
    }

    @NotNull
    @Override
    WebClient apply(@NotNull final WebClient client) {
        return client.query("resource", resourceReferences.stream().map(ResourceReference::toParamValue).collect(Collectors.toList()));
    }

    public static final class Builder {
        @NotNull
        private final List<ResourceReference> resourceReferences;

        private Builder(final ResourceReference resourceReference) {
            this.resourceReferences = new ArrayList<>();
            this.resourceReferences.add(resourceReference);
        }

        public Builder or(@NotNull final String serviceKey, @NotNull final String resourceKey) {
            resourceReferences.add(ResourceReference.createFor(serviceKey, resourceKey));
            return this;
        }

        public ResourceFilter build() {
            return new ResourceFilter(resourceReferences);
        }
    }

    private static final class ResourceReference {
        private final String serviceKey;
        private final String resourceKey;

        private static ResourceReference createFor(final String serviceKey, final String resourceKey) {
            return new ResourceReference(serviceKey, resourceKey);
        }

        private ResourceReference(final String serviceKey, final String resourceKey) {
            this.serviceKey = serviceKey;
            this.resourceKey = resourceKey;
        }

        @NotNull
        private String toParamValue() {
            return "/" + serviceKey + "/" + resourceKey;
        }
    }
}
