package ru.yandex.webmaster3.storage.checklist.service;

import java.util.UUID;

import com.google.common.base.Preconditions;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.webmaster3.core.checklist.data.SiteProblemTypeEnum;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.sitemap.HostSitemap;
import ru.yandex.webmaster3.core.sitemap.HostSitemapInfo;
import ru.yandex.webmaster3.storage.sitemap.SitemapRecrawlRequestService;
import ru.yandex.webmaster3.storage.sitemap.dao.SitemapsCHDao;

/**
 * @author akhazhoyan 10/2018
 */
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public final class SitemapRecrawlRechecker implements ProblemRechecker {
    private static final Duration NO_MODIFICATIONS_PROBLEM_PERIOD = Duration.standardDays(90);

    private final SitemapRecrawlRequestService sitemapRecrawlRequestService;
    private final SitemapsCHDao sitemapsCHDao;

    @Override
    public void recheck(WebmasterHostId hostId, SiteProblemTypeEnum problemType) {
        Preconditions.checkNotNull(hostId);
        Preconditions.checkArgument(problemType == SiteProblemTypeEnum.ERRORS_IN_SITEMAPS || problemType == SiteProblemTypeEnum.NO_SITEMAP_MODIFICATIONS);

        sitemapsCHDao.getSitemapInfos(hostId, null, null, 1000).forEach(sitemapInfo -> {
            if (sitemapInfo.getErrorCount() > 0 || sitemapInfo.getLastUrlsChange().isBefore(DateTime.now().minus(NO_MODIFICATIONS_PROBLEM_PERIOD))) {
                recrawl(sitemapInfo.toHostSitemap(), sitemapInfo.toHostSitemapInfo(), hostId);
            }
        });
    }

    private void recrawl(HostSitemap sitemap, HostSitemapInfo sitemapInfo, WebmasterHostId hostId) {
        Preconditions.checkNotNull(sitemap);
        Preconditions.checkNotNull(hostId);
        UUID sitemapId = sitemap.getSitemapId();
        if (sitemapInfo == null) {
            log.debug("Could not find info for sitemap {} for host {}", sitemap.getSitemapId(), hostId);
            return;
        }

        DateTime lastRequestTime = sitemapRecrawlRequestService.getLastRequestTime(hostId, sitemapId);
        boolean isPending = lastRequestTime != null;
        if (sitemapInfo.getLastAccessDate() != null) {
            isPending = isPending && !sitemapInfo.getLastAccessDate().isAfter(lastRequestTime);
        }
        if (isPending) {
            log.debug("There is already a pending request for sitemap {} for host {}", sitemap.getSitemapId(), hostId);
            return;
        }
        log.info("Create request with host = {} and sitemapId = {}", hostId, sitemapId);
        sitemapRecrawlRequestService.createRequest(hostId, sitemapId, sitemap.getInfo().getParentSitemapId(), sitemap.getSitemapUrl());
    }
}
