package ru.yandex.wmconsole.servantlet.offline;

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.AvailableEnum;
import ru.yandex.wmconsole.data.info.AvailableInfo;
import ru.yandex.wmconsole.data.info.BriefHostInfo;
import ru.yandex.wmconsole.data.info.OfflineLinksInfo;
import ru.yandex.wmconsole.data.wrappers.OfflineLinksAvailableWrapper;
import ru.yandex.wmconsole.data.wrappers.OfflineLinksInfoWrapper;
import ru.yandex.wmconsole.servantlet.WMCAuthorizedHostOperationServantlet;
import ru.yandex.wmconsole.service.LinkType;
import ru.yandex.wmconsole.service.OfflineLinksService;
import ru.yandex.wmconsole.service.error.WMCUserProblem;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;

public abstract class AbstractOfflineLinksServantlet extends WMCAuthorizedHostOperationServantlet {
    private static final String PARAM_NEW_OFFLINE = "new-offline";

    protected OfflineLinksService offlineLinksService;

    @Override
    public void doProcess(ServRequest req, ServResponse res, long userId) throws UserException, InternalException {
        BriefHostInfo hostInfo = getHostInfoAndVerify(req, userId);
        Boolean newOffline = getBooleanParam(req, PARAM_NEW_OFFLINE, false);
        if (newOffline) {
            OfflineLinksInfo info = offlineLinksService.getOfflineLinksInfo(
                    userId, req.getUserId(), hostInfo, getLinkType());
            checkState(info.getAvailable(), userId, hostInfo);
            offlineLinksService.userDownloaded(userId, hostInfo, getLinkType());
            res.addData(new OfflineLinksInfoWrapper(info));
        } else {
            AvailableInfo available = offlineLinksService.isNewAvailable(userId, req.getUserId(), hostInfo, getLinkType());
            checkState(available.getAvailable(), userId, hostInfo);
            offlineLinksService.userDownloaded(userId, hostInfo, getLinkType());
            res.addData(new OfflineLinksAvailableWrapper(available));
        }
    }

    private void checkState(AvailableEnum available, long userId, BriefHostInfo hostInfo) throws UserException {
        if (available == AvailableEnum.OPTION_DISABLED) {
            throw new UserException(WMCUserProblem.OFFLINE_OPTION_DISABLED, "Option 'Offline links' is disabled for given user" + userId);
        }
        if (available == AvailableEnum.NOT_READY) {
            throw new UserException(WMCUserProblem.OFFLINE_FILE_NOT_READY, "File is not ready for given host " + hostInfo.getId());
        }
    }

    protected abstract LinkType getLinkType();

    @Required
    public void setOfflineLinksService(OfflineLinksService offlineLinksService) {
        this.offlineLinksService = offlineLinksService;
    }
}
