package ru.yandex.qe.dispenser.ws;

import java.util.Set;

import javax.ws.rs.BeanParam;
import javax.ws.rs.DefaultValue;
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 javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.Authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import ru.yandex.qe.dispenser.api.v1.DiOrder;
import ru.yandex.qe.dispenser.api.v1.DiQuotaRequestHistoryEvent;
import ru.yandex.qe.dispenser.api.v1.DiQuotaRequestHistoryEventType;
import ru.yandex.qe.dispenser.api.v1.response.DiListRelativePageResponse;
import ru.yandex.qe.dispenser.domain.Person;
import ru.yandex.qe.dispenser.domain.QuotaChangeRequestHistoryEvent;
import ru.yandex.qe.dispenser.domain.dao.history.request.QuotaChangeRequestHistoryDao;
import ru.yandex.qe.dispenser.domain.util.RelativePage;
import ru.yandex.qe.dispenser.domain.util.RelativePageInfo;
import ru.yandex.qe.dispenser.swagger.DispenserSecurityDefinition;
import ru.yandex.qe.dispenser.swagger.SwaggerTags;
import ru.yandex.qe.dispenser.ws.param.HistoryParams;
import ru.yandex.qe.dispenser.ws.param.QuotaChangeRequestFilterParam;
import ru.yandex.qe.dispenser.ws.param.QuotaChangeRequestFilterParamConverter;
import ru.yandex.qe.dispenser.ws.param.QuotaRequestHistoryParams;
import ru.yandex.qe.dispenser.ws.param.RelativePageParam;

import static ru.yandex.qe.dispenser.ws.QuotaChangeRequestService.REQUEST_ID;
import static ru.yandex.qe.dispenser.ws.param.RelativePageParam.DEFAULT_ORDER;
import static ru.yandex.qe.dispenser.ws.param.RelativePageParam.PAGE_ORDER;

@Controller
@Path("/v1/history/quota-requests")
@Produces(ServiceBase.APPLICATION_JSON_UTF_8)
@Api(tags = {SwaggerTags.DISPENSER_API}, authorizations = {@Authorization(value = DispenserSecurityDefinition.AUTHORIZATION_SCHEME_NAME)})
public class QuotaChangeRequestHistoryService extends ServiceBase {
    private static final String EVENT_ID = "event_id";


    @Autowired
    private QuotaChangeRequestHistoryDao quotaChangeRequestHistoryDao;

    @Autowired
    private QuotaChangeRequestFilterParamConverter filterParamConverter;

    @GET
    @Access
    @Path("/{" + REQUEST_ID + "}")
    public DiListRelativePageResponse<DiQuotaRequestHistoryEvent> byRequest(@PathParam(REQUEST_ID) final long requestId,
                                                                            @QueryParam(RelativePageParam.PAGE_SIZE)
                                                                            @DefaultValue(RelativePageParam.DEFAULT_PAGE_SIZE) final Long pageSize,
                                                                            @QueryParam(RelativePageParam.FROM_ID) final Long fromId,
                                                                            @Context final UriInfo uriInfo,
                                                                            @QueryParam(HistoryParams.FROM) final String from,
                                                                            @QueryParam(HistoryParams.TO) final String to,
                                                                            @QueryParam(HistoryParams.PERFORMER) final Set<Person> performers,
                                                                            @QueryParam(HistoryParams.TVM_ID) final Set<Long> tvmIds,
                                                                            @QueryParam(QuotaRequestHistoryParams.EVENT_TYPE) final Set<DiQuotaRequestHistoryEventType> eventTypes,
                                                                            @QueryParam(PAGE_ORDER) @DefaultValue(DEFAULT_ORDER) final DiOrder pageOrder) {
        final RelativePageParam pageParam = new RelativePageParam(pageSize, fromId, uriInfo, pageOrder);
        final QuotaRequestHistoryParams historyParams = new QuotaRequestHistoryParams(from, to, performers, tvmIds, eventTypes);

        final RelativePageInfo pageInfo = getPageInfo(pageParam);
        final RelativePage<QuotaChangeRequestHistoryEvent> page = quotaChangeRequestHistoryDao.readHistoryByRequest(requestId,
                historyParams.toHistoryFilter(), pageInfo, pageOrder);
        return toResponsePage(pageParam, page, QuotaChangeRequestHistoryEvent::toView);
    }

    @GET
    @Access
    public DiListRelativePageResponse<DiQuotaRequestHistoryEvent> filter(@BeanParam final QuotaChangeRequestFilterParam filterParam,
                                                                         @QueryParam(HistoryParams.FROM) final String from,
                                                                         @QueryParam(HistoryParams.TO) final String to,
                                                                         @QueryParam(HistoryParams.PERFORMER) final Set<Person> performers,
                                                                         @QueryParam(HistoryParams.TVM_ID) final Set<Long> tvmIds,
                                                                         @QueryParam(QuotaRequestHistoryParams.EVENT_TYPE) final Set<DiQuotaRequestHistoryEventType> eventTypes,
                                                                         @QueryParam(RelativePageParam.PAGE_SIZE)
                                                                         @DefaultValue(RelativePageParam.DEFAULT_PAGE_SIZE) final Long pageSize,
                                                                         @QueryParam(RelativePageParam.FROM_ID) final Long fromId,
                                                                         @Context final UriInfo uriInfo,
                                                                         @QueryParam(PAGE_ORDER) @DefaultValue(DEFAULT_ORDER) final DiOrder pageOrder) {
        final QuotaRequestHistoryParams historyParams = new QuotaRequestHistoryParams(from, to, performers, tvmIds, eventTypes);
        final RelativePageParam pageParam = new RelativePageParam(pageSize, fromId, uriInfo, pageOrder);

        final RelativePage<QuotaChangeRequestHistoryEvent> events = filterParamConverter.fromParam(filterParam)
                .map(f -> quotaChangeRequestHistoryDao.read(f, historyParams.toHistoryFilter(),
                        getPageInfo(pageParam), pageOrder))
                .orElse(RelativePage.empty());

        return toResponsePage(pageParam, events, QuotaChangeRequestHistoryEvent::toView);
    }

    @GET
    @Access
    @Path("/events/{" + EVENT_ID + "}")
    public DiQuotaRequestHistoryEvent event(@PathParam(EVENT_ID) final long eventId) {
        final QuotaChangeRequestHistoryEvent event = quotaChangeRequestHistoryDao.read(eventId);
        return event.toView();
    }
}
