package ru.yandex.qe.dispenser.ws;

import java.util.Set;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

import io.swagger.annotations.Api;
import io.swagger.annotations.Authorization;
import org.springframework.stereotype.Controller;

import ru.yandex.qe.dispenser.api.v1.DiCheckCompareType;
import ru.yandex.qe.dispenser.api.v1.DiCheckValueType;
import ru.yandex.qe.dispenser.api.v1.DiUnit;
import ru.yandex.qe.dispenser.domain.Project;
import ru.yandex.qe.dispenser.domain.Quota;
import ru.yandex.qe.dispenser.domain.QuotaCompareType;
import ru.yandex.qe.dispenser.domain.QuotaCompareValue;
import ru.yandex.qe.dispenser.domain.QuotaSpec;
import ru.yandex.qe.dispenser.domain.QuotaView;
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.QuotaCheckParam;
import ru.yandex.qe.dispenser.ws.param.QuotaSpecFilterParam;

@Controller
@Path("/v1/check-quotas")
@ParametersAreNonnullByDefault
@org.springframework.stereotype.Service("quota-check")
@Api(tags = {SwaggerTags.DISPENSER_API}, authorizations = {@Authorization(value = DispenserSecurityDefinition.AUTHORIZATION_SCHEME_NAME)})
public class QuotaCheckService {

    public static final int STATUS_OK = Response.Status.OK.getStatusCode();
    public static final int STATUS_FAIL = Response.Status.ACCEPTED.getStatusCode();

    @GET
    public Response check(@QueryParam(QuotaCheckParam.PROJECT_KEY) final Project project,
                          @QueryParam(QuotaCheckParam.QUOTA_SPEC_KEY) final QuotaSpecFilterParam quotaSpecKey,
                          @QueryParam(QuotaCheckParam.VALUE_TYPE) final DiCheckValueType valueType,
                          @QueryParam(QuotaCheckParam.VALUE) final Double value,
                          @Nullable @QueryParam(QuotaCheckParam.VALUE_UNIT) final DiUnit valueUnit,
                          @QueryParam(QuotaCheckParam.COMPARE_TYPE) final DiCheckCompareType compareTypeParam,
                          @QueryParam(QuotaCheckParam.SEGMENTS) final Set<String> segments) {
        final QuotaCheckParam quotaCheckParam = new QuotaCheckParam(project, quotaSpecKey, valueType, value, valueUnit, compareTypeParam, segments);
        final QuotaCheckParam.Value checkParams = quotaCheckParam.get();

        final QuotaSpec quotaSpec = checkParams.getQuotaSpecKey().get();

        final Quota.Key key = new Quota.Key(quotaSpec, checkParams.getProject(), checkParams.getSegments());
        final QuotaView quota = Hierarchy.get().getQuotaCache().getQuota(key);

        final QuotaCompareValue compareValue = QuotaCompareValue.of(checkParams.getCheckAmount());
        final QuotaCompareType compareType = QuotaCompareType.of(checkParams.getCompareType());


        final int status;

        if (compareValue.test(quota, compareType)) {
            status = STATUS_FAIL;
        } else {
            status = STATUS_OK;
        }

        final String body = String.format("%s: %s %s", quota, compareType.getTitle(), compareValue.toString());

        return Response.status(status).entity(body).build();
    }
}
