package ru.yandex.wmconsole.servantlet.api;

import java.util.Date;
import java.util.HashMap;
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.common.util.db.OrderByClause;
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.info.WMCTopInfo;
import ru.yandex.wmconsole.data.wrappers.WMCTopInfoItemWrapper;
import ru.yandex.wmconsole.data.wrappers.api.ApiTopInfoWrapper;
import ru.yandex.wmconsole.error.ClientException;
import ru.yandex.wmconsole.service.HostDbHostInfoService;
import ru.yandex.wmconsole.service.WMCCustomRegionService;
import ru.yandex.wmconsole.service.WMCTopInfoService;
import ru.yandex.wmtools.common.data.info.RegionInfo;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.service.TopType;
import ru.yandex.wmtools.common.service.TopTypeEnum;

/**
 * @author ailyin
 */
public class ApiTopQueriesServantlet extends AbstractApiServantlet {
    private WMCTopInfoService topInfoService;
    private HostDbHostInfoService hostDbHostInfoService;
    private WMCCustomRegionService customRegionService;

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

        BriefHostInfo briefHostInfo = getHostInfo(req, false, userId, true, true, res, false, false);
        if (briefHostInfo == null) {
            return;
        }
        HostDbHostInfo hostDbHostInfo = hostDbHostInfoService.getHostDbHostInfo(briefHostInfo.getName());

        int region = 0; // todo (minor) introduce constant
        Date date = topInfoService.getLatestInfoDateIfDateIsNull(region, hostDbHostInfo, null, true);

        List<RegionInfo> keyRegions = customRegionService.getKeyRegionsForHostAndDate(hostDbHostInfo, date);

        TopType topType = new TopType(TopTypeEnum.SHOWS, WMCTopInfoService.FIELD_SHOWS);
        OrderByClause orderBy = new OrderByClause(req, topType.getOrderByDbField(), false, new TopInfoCorrespondence());
        WMCTopInfo showsTopInfo = topInfoService.getTopInfo(region, keyRegions, hostDbHostInfo, date, orderBy,
                topType.getTopTypeEnum(), true);

        topType = new TopType(TopTypeEnum.CLICKS, WMCTopInfoService.FIELD_CLICKS);
        orderBy = new OrderByClause(req, topType.getOrderByDbField(), false, new TopInfoCorrespondence());
        WMCTopInfo clicksTopInfo = topInfoService.getTopInfo(region, keyRegions, hostDbHostInfo, date, orderBy,
                topType.getTopTypeEnum(), true);

        res.addData(new ApiTopInfoWrapper(showsTopInfo, clicksTopInfo));
    }

    private static class TopInfoCorrespondence extends HashMap<String, String> {
        public TopInfoCorrespondence() {
            put(WMCTopInfoItemWrapper.TAG_QUERY, WMCTopInfoService.FIELD_QUERY);
            put(WMCTopInfoItemWrapper.TAG_POSITION, WMCTopInfoService.FIELD_POSITION);
            put(WMCTopInfoItemWrapper.TAG_CLICKS, WMCTopInfoService.FIELD_CLICKS);
            put(WMCTopInfoItemWrapper.TAG_SHOWS, WMCTopInfoService.FIELD_SHOWS);
        }
    }

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

    @Required
    public void setTopInfoService(WMCTopInfoService topInfoService) {
        this.topInfoService = topInfoService;
    }

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

    @Required
    public void setCustomRegionService(WMCCustomRegionService customRegionService) {
        this.customRegionService = customRegionService;
    }
}
