package ru.yandex.wmconsole.servantlet.spider;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.NavigableMap;

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.common.util.collections.Pair;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.info.HostDbHostInfo;
import ru.yandex.wmconsole.data.info.spider.SpiderCodesGroupInfo;
import ru.yandex.wmconsole.data.wrappers.highchart.JsonHighchartPlotDataWrapper;
import ru.yandex.wmconsole.servantlet.WMCAuthorizedHostOperationServantlet;
import ru.yandex.wmconsole.service.HostDbHostInfoService;
import ru.yandex.wmconsole.service.SpiderInfoService;
import ru.yandex.wmtools.common.data.plot.DateLongPlotHelper;
import ru.yandex.wmtools.common.data.plot.DatePlotHelper;
import ru.yandex.wmtools.common.data.plot.HighchartPlotDataWrapper;
import ru.yandex.wmtools.common.data.plot.PlotHelper;
import ru.yandex.wmtools.common.data.plot.UnixTimestampDateFormat;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;

/**
 * @author avhaliullin
 */
public class SpiderHttpCodesPlotDataServantlet extends WMCAuthorizedHostOperationServantlet {
    private static final Logger log = LoggerFactory.getLogger(SpiderHttpCodesPlotDataServantlet.class);

    private static final String PARAM_CODES = "code";
    private static final String PARAM_GROUP = "group";
    private static final String HTTP_CODES_STATS_PLOT_NAME = "http-codes";
    private static final String PARAM_JSON = "json";

    private static final DatePlotHelper<Long> longPlotHelper = new DateLongPlotHelper(PlotHelper.InterpolateMode.ZERO);

    static {
        longPlotHelper.setPeriod(15, Calendar.MINUTE);
        longPlotHelper.setDateFormat(new UnixTimestampDateFormat(true));
    }

    private SpiderInfoService spiderInfoService;
    private HostDbHostInfoService hostDbHostInfoService;

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

        BriefHostInfo briefHostInfo = getHostInfoAndVerify(req, userId);
        HostDbHostInfo hostInfo = hostDbHostInfoService.getHostDbHostInfo(briefHostInfo.getName());

        List<String> codes = req.getMultiParams(PARAM_CODES);
        String group = getStringParam(req, PARAM_GROUP);

        List<SpiderCodesGroupInfo> groups = spiderInfoService.getCodesGroupInfos(codes);

        Pair<List<String>, List<NavigableMap<Date, Long>>> plot;

        Boolean json = getBooleanParam(req, PARAM_JSON, false);

        if (group != null) {
            plot = new Pair<List<String>, List<NavigableMap<Date, Long>>>(new ArrayList<String>(), new ArrayList<NavigableMap<Date, Long>>());
            for (SpiderCodesGroupInfo groupInfo : groups) {
                if (groupInfo.getName().equals(group.toLowerCase())) {
                    plot = spiderInfoService.getHttpCodesGroupsPlotData(hostInfo, groupInfo.getSubgroups());
                    break;
                }
            }
        } else {
            plot = spiderInfoService.getHttpCodesGroupsPlotData(hostInfo, groups);
        }

        if (json) {
            res.addData(new JsonHighchartPlotDataWrapper<Date, Long>(HTTP_CODES_STATS_PLOT_NAME, plot.getSecond(), plot.getFirst(), longPlotHelper));
        } else {
            res.addData(new HighchartPlotDataWrapper<Date, Long>(HTTP_CODES_STATS_PLOT_NAME, plot.getSecond(), plot.getFirst(), longPlotHelper, true));
        }
    }

    @Required
    public void setSpiderInfoService(SpiderInfoService spiderInfoService) {
        this.spiderInfoService = spiderInfoService;
    }

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