package ru.yandex.wmconsole.viewer.api.servantlet.sitemap;

import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.annotation.Required;

import ru.yandex.common.framework.core.ServRequest;
import ru.yandex.common.framework.core.ServResponse;
import ru.yandex.misc.db.q.SqlLimits;
import ru.yandex.wmconsole.authorization.ApiOAuthPermission;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.info.HostDbHostInfo;
import ru.yandex.wmconsole.data.sitemaps.SitemapSourceEnum;
import ru.yandex.wmconsole.error.ClientException;
import ru.yandex.wmconsole.error.ClientProblem;
import ru.yandex.wmconsole.servantlet.api.AbstractApiServantlet;
import ru.yandex.wmconsole.service.HostDbHostInfoService;
import ru.yandex.wmconsole.util.PageUtils;
import ru.yandex.wmconsole.viewer.api.ApiUrl;
import ru.yandex.wmconsole.viewer.api.SitemapIdApiFormatter;
import ru.yandex.wmconsole.viewer.api.servantlet.ApiParameterNames;
import ru.yandex.wmconsole.viewer.sitemap.SitemapId;
import ru.yandex.wmconsole.viewer.sitemap.SitemapLink;
import ru.yandex.wmconsole.viewer.sitemap.SitemapService2;
import ru.yandex.wmconsole.viewer.sitemap.dao.TblSitemapIndexMetaDao;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;

/**
 * @author aherman
 */
public class ApiListSitemapChildrensServantlet extends AbstractApiServantlet {
    private static final int DEFAULT_PAGE_SIZE = 50;

    private SitemapService2 sitemapService2;
    private TblSitemapIndexMetaDao tblSitemapIndexMetaDao;
    private HostDbHostInfoService hostDbHostInfoService;
    private ApiUrl apiUrl;

    @Override
    protected void apiDoProcess(ServRequest req, ServResponse res, long userId) throws ClientException, InternalException {

        int pageNumber = req.getParamAsInt(ApiParameterNames.PAGE, 0);
        String externalSitemapId = getRequiredStringParam(req, ApiParameterNames.SITEMAP_ID);
        SitemapId sitemapId = SitemapIdApiFormatter.parseFromExternalId(externalSitemapId);

        if (sitemapId.getSitemapSource() != SitemapSourceEnum.LATEST) {
            throw new ClientException(ClientProblem.ILLEGAL_PARAM_VALUE, "Not sitemap index", ApiParameterNames.SITEMAP_ID);
        }

        try {
            BriefHostInfo briefHostInfo = getHostInfo(req, false, userId, true, true, res, false, false);
            HostDbHostInfo hostDbHostInfo = hostDbHostInfoService.getHostDbHostInfo(briefHostInfo.getName());
            int sitemapCount = tblSitemapIndexMetaDao.countSitemapIndexChildren(hostDbHostInfo, sitemapId);

            PageUtils.Pager page = PageUtils.getPage(pageNumber, DEFAULT_PAGE_SIZE, sitemapCount);
            List<SitemapLink> sitemapLinks = Collections.emptyList();

            if (!page.isEmpty()) {
                sitemapLinks = sitemapService2.getSitemapIndexChildren(hostDbHostInfo, sitemapId,
                        SqlLimits.range(page.toRangeStart(), page.getPageSize()));
            }

            ApiUrl.V2.Host host = apiUrl.v2().host(briefHostInfo.getId());
            res.addData(new SitemapListWrapper(sitemapLinks, sitemapCount, false, host));
        } catch (UserException e) {
            // TODO: create appropriate error
            throw new ClientException(ClientProblem.ILLEGAL_PARAM_VALUE, e.getMessage(), e);
        }
    }

    @Override
    public ApiOAuthPermission getRequiredPermission() {
        return ApiOAuthPermission.COMMON_OPERATIONS;
    }

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

    @Required
    public void setApiUrl(ApiUrl apiUrl) {
        this.apiUrl = apiUrl;
    }

    @Required
    public void setTblSitemapIndexMetaDao(TblSitemapIndexMetaDao tblSitemapIndexMetaDao) {
        this.tblSitemapIndexMetaDao = tblSitemapIndexMetaDao;
    }

    @Required
    public void setSitemapService2(SitemapService2 sitemapService2) {
        this.sitemapService2 = sitemapService2;
    }
}
