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

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

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

import ru.yandex.qe.dispenser.api.v1.request.DiEntity;
import ru.yandex.qe.dispenser.api.v1.response.DiListResponse;
import ru.yandex.qe.dispenser.client.v1.builder.UpdateEntitiesRequestBuilder;

class UpdateEntitiesRequestBuilderImpl implements UpdateEntitiesRequestBuilder.InService.ByEntitySpecification {
    @NotNull
    private final Supplier<WebClient> clients;

    @Nullable
    private String service;
    @Nullable
    private String entitySpecification;
    @NotNull
    private final List<DiEntity> entities = new ArrayList<>();

    UpdateEntitiesRequestBuilderImpl(@NotNull final Supplier<WebClient> clients) {
        this.clients = clients;
    }

    @NotNull
    @Override
    public InService inService(@NotNull final String serviceKey) {
        this.service = serviceKey;
        return this;
    }

    @NotNull
    @Override
    public ByEntitySpecification bySpecification(@NotNull final String entitySpecificationKey) {
        this.entitySpecification = entitySpecificationKey;
        return this;
    }

    @NotNull
    @Override
    public ByEntitySpecification prolong(@NotNull final String entityKey, @NotNull final Duration ttlFromNow) {
        Objects.requireNonNull(entitySpecification, "Call bySpecification() before!");
        final DiEntity entityToUpdate = DiEntity.withKey(entityKey)
                .bySpecification(entitySpecification)
                .withTtl(ttlFromNow)
                .build();
        entities.add(entityToUpdate);
        return this;
    }

    @NotNull
    @Override
    public DiListResponse<DiEntity> perform() {
        Objects.requireNonNull(service, "Call inService() before!");
        if (entities.isEmpty()) {
            throw new IllegalArgumentException("Prolong at least one entity!");
        }
        final List<DiEntity> updatedEntities = new ArrayList<>();
        for (final DiEntity entityToUpdate : entities) {
            // TODO: batch mode
            final DiEntity updatedEntity = clients.get()
                    .path(String.format("/entities/%s/%s/%s", service, entityToUpdate.getSpecificationKey(), entityToUpdate.getKey()))
                    .post(entityToUpdate, DiEntity.class);
            updatedEntities.add(updatedEntity);
        }
        return new DiListResponse<>(updatedEntities);
    }
}
