package ru.yandex.webmaster.viewer.http.servantlet.xml.limit;

import org.springframework.beans.factory.annotation.Required;
import ru.yandex.common.framework.user.UserInfo;
import ru.yandex.webmaster.common.http.RequestFilter;
import ru.yandex.webmaster.common.http.StandardAction;
import ru.yandex.webmaster.common.http.response.HostResponse;
import ru.yandex.webmaster.common.http.response.UserResponse;
import ru.yandex.wmconsole.data.info.limits.HostLimitsInfo;
import ru.yandex.wmconsole.data.info.limits.HostsAndLimitsInfo;
import ru.yandex.wmconsole.service.UsersHostsService;
import ru.yandex.wmconsole.service.XmlLimitsService;
import ru.yandex.wmconsole.util.BackportedIdUtils;
import ru.yandex.wmconsole.util.PageUtils;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.UserException;
import ru.yandex.wmtools.common.service.UserService;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author aherman
 */
public class GetLimitsByFilterAction extends StandardAction<GetLimitsByFilterRequest, GetLimitsByFilterResponse> {
    private XmlLimitsService xmlLimitsService;
    private UsersHostsService usersHostsService;
    private UserService userService;

    @Override
    public GetLimitsByFilterResponse process(GetLimitsByFilterRequest request) throws UserException, InternalException {
        super.process(request);
        PageUtils.Pager pager = PageUtils.getPage(request.getPage(), request.getPageSize());

        List<HostLimitsInfo> limits = xmlLimitsService
                .getLimits(request.getUserId(), request.getHostnamePart(), request.getOrder(), pager.toRangeStart(), pager.getPageSize());
        List<GetLimitsByFilterResponse.HostLimit> hosts = new LinkedList<>();
        for (HostLimitsInfo limit : limits) {
            String unicodeHostName = BackportedIdUtils.toHostString(BackportedIdUtils.urlToHostId(limit.getHostname()), true, true, false);
            HostResponse hostResponse = new HostResponse(limit.getHostId(), unicodeHostName, limit.getHostname());
            UserInfo limitOwnerUserInfo = userService.getUserInfo(limit.getLimitOwnerUserId());
            UserResponse owner = null;
            if (limitOwnerUserInfo != null) {
                owner = new UserResponse(limitOwnerUserInfo.getUserId(), limitOwnerUserInfo.getLogin());
            }
            List<UserInfo> verifiedUserForHost = usersHostsService.getVerifiedUserForHost(limit.getHostId(), false);
            List<UserResponse> verifiedUsers = new ArrayList<>(verifiedUserForHost.size());
            for (UserInfo userInfo : verifiedUserForHost) {
                verifiedUsers.add(new UserResponse(userInfo.getUserId(), userInfo.getLogin()));
            }
            GetLimitsByFilterResponse.HostLimit host = new GetLimitsByFilterResponse.HostLimit(limit.getLimits(), hostResponse, owner,
                    verifiedUsers);
            hosts.add(host);
        }
        HostsAndLimitsInfo totalHostsAndLimits =
                xmlLimitsService.getHostsAndLimits(request.getUserId(), null);
        HostsAndLimitsInfo filteredHostsAndLimits =
                xmlLimitsService.getHostsAndLimits(request.getUserId(), request.getHostnamePart());
        GetLimitsByFilterResponse response =
                new GetLimitsByFilterResponse(totalHostsAndLimits, filteredHostsAndLimits, hosts);
        return response;
    }

    @Override
    public List<Class<? extends RequestFilter>> getRequestFilters() {
        List<Class<? extends RequestFilter>> requestFilters = super.getRequestFilters();
        requestFilters.add(GetLimitsByFilterRequest.HostnameFilter.class);
        return requestFilters;
    }

    @Required
    public void setXmlLimitsService(XmlLimitsService xmlLimitsService) {
        this.xmlLimitsService = xmlLimitsService;
    }

    @Required
    public void setUsersHostsService(UsersHostsService usersHostsService) {
        this.usersHostsService = usersHostsService;
    }

    @Required
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
