package ru.yandex.wmconsole.servantlet.messages.options;

import java.util.ArrayList;
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.wmconsole.data.NotificationChannelEnum;
import ru.yandex.wmconsole.data.UserNotificationOptions;
import ru.yandex.wmconsole.data.info.ForeignPairInfo;
import ru.yandex.wmconsole.data.info.NotificationOptionInfo;
import ru.yandex.wmconsole.data.info.UserOptionsInfo;
import ru.yandex.wmconsole.data.wrappers.ForeignPairWrapper;
import ru.yandex.wmconsole.data.wrappers.InactiveChannelsWrapper;
import ru.yandex.wmconsole.data.wrappers.StringWrapper;
import ru.yandex.wmconsole.data.wrappers.UserNotificationOptionsWrapper;
import ru.yandex.wmconsole.servantlet.WMCAuthenticationServantlet;
import ru.yandex.wmconsole.service.ForeignServicesService;
import ru.yandex.wmconsole.service.NotificationOptionsService;
import ru.yandex.wmconsole.service.UserOptionsService;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;
import ru.yandex.wmtools.common.service.ValidatorService;
import ru.yandex.wmtools.common.util.XmlConvertableCollectionWrapper;

/**
 * @author Andrey Mima (amima@yandex-team.ru)
 */
public class NotificationOptionsInfoServantlet extends WMCAuthenticationServantlet {
    private static final String EMPTY = "";
    private static final String TAG_PERCENT = "percent";
    private static final String TAG_DEFAULT_EMAIL = "default-email";
    private static final String TAG_DEFAULT_ERRORSGROW = "default-errorsgrow";
    private static final String TAG_FOREIGN_SERVICES = "foreign-services";
    private static final String TAG_SERVICE_ITEM = "service";

    private NotificationOptionsService notificationOptionsService;
    private UserOptionsService userOptionsService;
    private ValidatorService validatorService;
    private ForeignServicesService foreignServicesService;

    @Override
    public void doProcess(ServRequest req, ServResponse res, long userId)
            throws InternalException, UserException {
        checkService(notificationOptionsService, NotificationOptionsService.class);
        checkService(userOptionsService, UserOptionsService.class);
        assertUserExists(userId);

        UserNotificationOptions userNotificationOptions =
                notificationOptionsService.getUserNotificationOptions(userId);
        res.addData(new UserNotificationOptionsWrapper(userNotificationOptions, false));

        UserNotificationOptions defaultOptions = new UserNotificationOptions(userId);
        for (NotificationOptionInfo defaultOption : NotificationOptionsService.getDefaultOptions()) {
            defaultOptions.addNotificationOption(defaultOption);
        }
        res.addData(new UserNotificationOptionsWrapper(defaultOptions, true));

        UserOptionsInfo userOptions = userOptionsService.getUserOptions(userId);
        Integer errorsGrow = userOptions.getErrorsGrow();

        if (errorsGrow != null) {
            res.addData(new StringWrapper(errorsGrow.toString(), TAG_PERCENT));
        }
        res.addData(new InactiveChannelsWrapper(getInactiveChannels(userOptions)));

        List<ForeignPairInfo> activeForeignServices = foreignServicesService.getActiveForeignServicesExtended(userId);
        XmlConvertableCollectionWrapper activeForeignServicesWrapped =
                XmlConvertableCollectionWrapper.wrap(activeForeignServices, ForeignPairWrapper.class, "foreign-services");
        res.addData(activeForeignServicesWrapped);

        String login = getUserInfoService().getUserInfo(userId).getLogin();
        String defaultEmail = validatorService.getDefaultEmail(userId, login);
        res.addData(new StringWrapper(defaultEmail, TAG_DEFAULT_EMAIL));
        res.addData(new StringWrapper(UserOptionsService.DEFAULT_ERRORS_GROW.toString(), TAG_DEFAULT_ERRORSGROW));
    }

    private List<NotificationChannelEnum> getInactiveChannels(UserOptionsInfo userOptions) {
        List<NotificationChannelEnum> inactiveChannels = new ArrayList<NotificationChannelEnum>();

        if (userOptions.getEmail() == null || EMPTY.equals(userOptions.getEmail())) {
            inactiveChannels.add(NotificationChannelEnum.EMAIL);
        }

        if ((userOptions.getPhone() == null) || userOptions.getPhone() == 0) {
            inactiveChannels.add(NotificationChannelEnum.SMS);
        }

        return inactiveChannels;
    }

    @Required
    public void setNotificationOptionsService(NotificationOptionsService notificationOptionsService) {
        this.notificationOptionsService = notificationOptionsService;
    }

    @Required
    public void setUserOptionsService(UserOptionsService userOptionsService) {
        this.userOptionsService = userOptionsService;
    }

    @Required
    public void setValidatorService(ValidatorService validatorService) {
        this.validatorService = validatorService;
    }

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