package ru.yandex.wmconsole.servantlet.notify;

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.framework.core.SimpleErrorInfo;
import ru.yandex.wmconsole.data.NotificationTypeEnum;
import ru.yandex.wmconsole.notifier.handler.HostOwnersHandler;
import ru.yandex.wmconsole.notifier.handler.NotificationHandler;
import ru.yandex.wmconsole.service.ForeignServicesService;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.servantlet.AbstractServantlet;

/**
 * @author Andrey Mima (amima@yandex-team.ru)
 */
public class NotifyServantlet extends AbstractServantlet {
    private static final Logger log = LoggerFactory.getLogger(NotifyServantlet.class);

    private static final String PARAM_XML_DATA = "xmldata";
    private static final String PARAM_NOTIFICATION_TYPE = "type";

    private NotificationHandler notificationHandler;
    private ForeignServicesService foreignServicesService;
    private HostOwnersHandler hostOwnersHandler;

    @Override
    protected void doProcess(ServRequest req, ServResponse res) throws InternalException {
        log.info("Java external request processing started");

        String xmlData = req.getParam(PARAM_XML_DATA);
        if ((xmlData == null) || (xmlData.length() == 0)) {
            log.warn("Invalid request parameter " + PARAM_XML_DATA);
            res.addErrorInfo(new SimpleErrorInfo("Parameter '" + PARAM_XML_DATA + "' is missing ot invalid"));
            return;
        }

        NotificationTypeEnum type = null;
        Integer integerType;
        try {
            integerType = Integer.parseInt(req.getParam(PARAM_NOTIFICATION_TYPE));
            if (integerType <= NotificationTypeEnum.MAX_VALUE) {
                type = NotificationTypeEnum.R.fromValueOrNull(integerType);
            } else if (!foreignServicesService.isActiveService(integerType)) {
                log.warn("Service number " +  integerType + " is unsupported or inactive");
                res.addErrorInfo(new SimpleErrorInfo("Service number '" + integerType + "' is unsupported or inactive"));
                return;
            }
        } catch (NumberFormatException e) {
            log.warn("Invalid request parameter " + PARAM_NOTIFICATION_TYPE);
            res.addErrorInfo(new SimpleErrorInfo("Parameter '" + PARAM_NOTIFICATION_TYPE + "' is missing ot invalid"));
            return;
        } catch (InternalException e) {
            log.error("InternalException in " + getClass().getName(), e);
            res.addErrorInfo(new SimpleErrorInfo("InternalException"));
            return;
        }

        if (type == null && integerType == null) {
            log.warn("Invalid request parameter " + PARAM_NOTIFICATION_TYPE);
            res.addErrorInfo(new SimpleErrorInfo("Parameter '" + PARAM_NOTIFICATION_TYPE + "' is missing ot invalid"));
            return;
        }

        if (type != null) {
            notificationHandler.handleNotification(type, xmlData);
        } else {
            hostOwnersHandler.handleServiceNotification(xmlData, integerType);
        }
    }

    @Required
    public void setNotificationHandler(NotificationHandler notificationHandler) {
        this.notificationHandler = notificationHandler;
    }

    @Required
    public void setForeignServicesService(ForeignServicesService foreignServicesService) {
        this.foreignServicesService = foreignServicesService;
    }

    @Required
    public void setHostOwnersHandler(HostOwnersHandler hostOwnersHandler) {
        this.hostOwnersHandler = hostOwnersHandler;
    }
}
