package ru.yandex.qe.dispenser.ws;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import io.swagger.annotations.Api;
import io.swagger.annotations.Authorization;
import org.jetbrains.annotations.NotNull;

import ru.yandex.qe.dispenser.api.v1.DiEntitySpec;
import ru.yandex.qe.dispenser.api.v1.response.DiListResponse;
import ru.yandex.qe.dispenser.domain.EntitySpec;
import ru.yandex.qe.dispenser.domain.Service;
import ru.yandex.qe.dispenser.domain.hierarchy.Hierarchy;
import ru.yandex.qe.dispenser.swagger.DispenserSecurityDefinition;
import ru.yandex.qe.dispenser.swagger.SwaggerTags;
import ru.yandex.qe.dispenser.ws.param.EntitySpecParam;

@Path("/v1/entity-specifications")
@Produces(ServiceBase.APPLICATION_JSON_UTF_8)
@org.springframework.stereotype.Service("entity-spec")
@Api(tags = {SwaggerTags.DISPENSER_API}, authorizations = {@Authorization(value = DispenserSecurityDefinition.AUTHORIZATION_SCHEME_NAME)})
public final class EntitySpecService extends ServiceBase {
    public static final String ENTITY_SPEC_KEY = "entity_spec_key";

    @GET
    @NotNull
    public DiListResponse<DiEntitySpec> filter(@QueryParam("service") @NotNull final List<Service> services) {
        ServiceEndpointUtils.memoizeService(services);
        if (services.isEmpty()) {
            return toView(Hierarchy.get().getEntitySpecReader().getAll());
        }
        return toView(Hierarchy.get().getEntitySpecReader().getByServices(services));
    }

    @GET
    @NotNull
    @Path("/{" + ServiceService.SERVICE_KEY + "}/{" + ENTITY_SPEC_KEY + "}")
    public DiEntitySpec read(@PathParam(ServiceService.SERVICE_KEY) final Service service,
                             @PathParam(ENTITY_SPEC_KEY) final String entitySpecKey) {
        final EntitySpecParam entitySpec = new EntitySpecParam(service, entitySpecKey);
        final EntitySpec entitySpecValue = entitySpec.get();
        ServiceEndpointUtils.memoizeServiceForEntitySpec(entitySpecValue);
        return entitySpecValue.toView();
    }

    @NotNull
    private DiListResponse<DiEntitySpec> toView(@NotNull final Collection<EntitySpec> specs) {
        return new DiListResponse<>(specs.stream().map(EntitySpec::toView).collect(Collectors.toList()));
    }
}
