package ru.yandex.webmaster3.viewer.http.spam;

import java.util.Set;

import lombok.RequiredArgsConstructor;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.webmaster3.core.http.request.RequestContext;
import ru.yandex.webmaster3.core.metrika.counters.CounterRequestTypeEnum;
import ru.yandex.webmaster3.core.spam.ShowCaptchaReason;
import ru.yandex.webmaster3.storage.spam.MetrikaCountersSpamStatsYDao;
import ru.yandex.webmaster3.viewer.http.filter.AbstractSpamCaptchaFilter;
import ru.yandex.webmaster3.viewer.http.metrika.counter.BindCounterAction;
import ru.yandex.webmaster3.viewer.http.metrika.counter.BindCounterRequest;

/**
 * @author avhaliullin
 * ttl 1 day
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BindMetrikaCounterCaptchaFilter extends AbstractSpamCaptchaFilter<BindCounterRequest> {
    private static final int SHOWN_COUNTERS_UNTIL_CAPTCHA = 5;

    private final MetrikaCountersSpamStatsYDao metrikaCountersSpamStatsYDao;

    @Override
    protected ShowCaptchaReason shouldShowCaptcha(RequestContext ctx, BindCounterRequest bindCounterRequest) {
        if (!isCaptchaNeeded(ctx)) {
            return null;
        }
        Set<Long> shownCounters = metrikaCountersSpamStatsYDao.getCountersForUser(bindCounterRequest.getUserId());
        if (!shownCounters.contains(bindCounterRequest.getCounterId()) && shownCounters.size() >= SHOWN_COUNTERS_UNTIL_CAPTCHA) {
            return ShowCaptchaReason.METRIKA_COUNTERS_SPAM;
        }
        if (!shownCounters.contains(bindCounterRequest.getCounterId())) {
            shownCounter(ctx, bindCounterRequest);
        }
        return null;
    }

    @Override
    protected void onCaptchaSolved(RequestContext ctx, BindCounterRequest bindCounterRequest) {
        shownCounter(ctx, bindCounterRequest);
    }

    private void shownCounter(RequestContext ctx, BindCounterRequest request) {
        if (isCaptchaNeeded(ctx)) {
            metrikaCountersSpamStatsYDao.addEvent(request.getUserId(), request.getCounterId(), DateTime.now());
        }
    }

    private boolean isCaptchaNeeded(RequestContext ctx) {
        return ctx.getAction() instanceof BindCounterAction && ((BindCounterAction) ctx.getAction()).getRequestType() == CounterRequestTypeEnum.CREATE;
    }
}
