package ru.yandex.wmconsole.servantlet.sitemaps;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import ru.yandex.common.framework.core.ServRequest;
import ru.yandex.common.framework.core.ServResponse;
import ru.yandex.webmaster.viewer.service.NewWebmasterProxyService;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.info.HostDbHostInfo;
import ru.yandex.wmconsole.data.info.SitemapInfo;
import ru.yandex.wmconsole.data.sitemaps.SitemapSourceEnum;
import ru.yandex.webmaster.viewer.sitemap.CurrentSitemapService;
import ru.yandex.wmconsole.servantlet.WMCAuthorizedHostOperationServantlet;
import ru.yandex.wmconsole.service.HostDbHostInfoService;
import ru.yandex.webmaster.common.sitemap.SitemapService;
import ru.yandex.wmconsole.service.error.WMCUserProblem;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;
import ru.yandex.wmtools.common.error.UserProblem;

public class RemoveSitemapServantlet extends WMCAuthorizedHostOperationServantlet {
    private static final Logger log = LoggerFactory.getLogger(RemoveSitemapServantlet.class);

    private static final String PARAM_REMOVE = "remove";
    private static final String PARAM_SOURCE = "source";

    private SitemapService sitemapService;
    private HostDbHostInfoService hostDbHostInfoService;
    private CurrentSitemapService currentSitemapService;
    private NewWebmasterProxyService newWebmasterProxyService;

    @Override
    public void doProcess(ServRequest req, ServResponse res, long userId) throws InternalException, UserException {
        final BriefHostInfo briefHostInfo = getHostInfoAndVerify(req, userId);
        final HostDbHostInfo hostDbHostInfo = hostDbHostInfoService.getHostDbHostInfo(briefHostInfo.getName());

        final Integer src = getIntParam(req, PARAM_SOURCE);
        final SitemapSourceEnum source = src != null ? SitemapSourceEnum.R.fromValueOrNull(src) : null;
        if (source == null) {
            throw new UserException(UserProblem.REQUIRED_PARAM_MISSED, "Parameter missing: source", PARAM_SOURCE);
        }

        Long sitemapId = getRequiredLongParam(req, PARAM_REMOVE);

        // Приводим идентификаторы к идентификаторам таблицы tbl_sitemaps (sitemap'ы в поиске)
        sitemapId = mapToInSearchSitemapIds(hostDbHostInfo, source, sitemapId);

        if (sitemapId != null) {
            List<Long> hostIds = sitemapService.getSitemapsHostIds(hostDbHostInfo, sitemapId);
            if (!hostIds.isEmpty()) {
                if ((hostIds.size() != 1) || !hostIds.get(0).equals(hostDbHostInfo.getHostDbHostId())) {
                    StringBuilder stringBuilder = new StringBuilder("Host id ");
                    stringBuilder.append(hostDbHostInfo.getHostDbHostId())
                            .append(" does not correspond to sitemap's ids.");

                    stringBuilder.append(sitemapId);
                    throw new UserException(WMCUserProblem.SITEMAP_NOT_OWNED, stringBuilder.toString());
                }
                SitemapInfo removedSitemap =
                        sitemapService.removeSitemap(hostDbHostInfo, briefHostInfo, userId, req.getUserId(), sitemapId);
                if (removedSitemap != null) {
                    try {
                        newWebmasterProxyService.removeSitemap(briefHostInfo, removedSitemap.getUrl());
                    } catch (InternalException e) {
                        log.error("Failed to remove sitemap " + removedSitemap.getUrl() +
                                " for host " + briefHostInfo.getName() + " from new WM", e);
                    }
                }
            }
        }
    }

    private Long mapToInSearchSitemapIds(HostDbHostInfo hostDbHostInfo, SitemapSourceEnum source, Long sitemapId)
            throws InternalException, UserException {

        if (source == SitemapSourceEnum.IN_SEARCH) {
            // delete sitemaps as is
            return sitemapId;
        }

        if (source == SitemapSourceEnum.LATEST) {
            // convert new sitemap id to old sitemap id
            return currentSitemapService.getSitemapIdInSearchByLatestSitemapId(hostDbHostInfo, sitemapId);
        }

        throw new UserException(UserProblem.ILLEGAL_PARAM_VALUE, "Unknown source", PARAM_SOURCE);
    }

    @Required
    public void setSitemapService(SitemapService sitemapService) {
        this.sitemapService = sitemapService;
    }

    @Required
    public void setHostDbHostInfoService(HostDbHostInfoService hostDbHostInfoService) {
        this.hostDbHostInfoService = hostDbHostInfoService;
    }

    @Required
    public void setCurrentSitemapService(CurrentSitemapService currentSitemapService) {
        this.currentSitemapService = currentSitemapService;
    }

    @Required
    public void setNewWebmasterProxyService(NewWebmasterProxyService newWebmasterProxyService) {
        this.newWebmasterProxyService = newWebmasterProxyService;
    }
}
