package ru.yandex.wmconsole.servantlet.spider;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
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.wmconsole.data.SpiderRequestResultEnum;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.info.HostDbHostInfo;
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 SpiderRequestResultsPlotDataServantlet extends WMCAuthorizedHostOperationServantlet {
    private static final Logger log = LoggerFactory.getLogger(SpiderRequestResultsPlotDataServantlet.class);

    private static final String PARAM_SHOW = "show";
    private static final String PARAM_JSON = "json";

    private static final String SPIDER_REQUESTS_PLOT_NAME = "spider-requests";
    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> labels = new ArrayList<String>();
        List<NavigableMap<Date, Long>> data = new ArrayList<NavigableMap<Date, Long>>();

        List<SpiderRequestResultEnum> toShow = new ArrayList<SpiderRequestResultEnum>();
        for (Integer val : getMultiParamInt(req, PARAM_SHOW)) {
            SpiderRequestResultEnum info = SpiderRequestResultEnum.R.fromValueOrNull(val);
            if (info != null) {
                toShow.add(info);
            }
        }

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

        Collections.sort(toShow, new Comparator<SpiderRequestResultEnum>() {
            @Override
            public int compare(SpiderRequestResultEnum o1, SpiderRequestResultEnum o2) {
                if (o2.equals(o1)) {
                    return 0;
                }
                if (SpiderRequestResultEnum.DNS_ERROR.equals(o2)) {
                    return -1;
                }
                if (SpiderRequestResultEnum.DNS_ERROR.equals(o1)) {
                    return 1;
                }
                if (SpiderRequestResultEnum.CONNECTION_FAILED.equals(o2)) {
                    return -1;
                }
                return 1;
            }
        });
        for (SpiderRequestResultEnum info : toShow) {
            data.add(spiderInfoService.getSpiderRequestResultsPlotData(hostInfo, info));
            labels.add(info.name().toLowerCase());
        }

        if (json) {
            res.addData(new JsonHighchartPlotDataWrapper<Date, Long>(SPIDER_REQUESTS_PLOT_NAME, data, labels, longPlotHelper));
        } else {
            res.addData(new HighchartPlotDataWrapper<Date, Long>(SPIDER_REQUESTS_PLOT_NAME, data, labels, longPlotHelper, true));
        }
    }

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

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