package ru.yandex.webmaster3.viewer.http.user;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import lombok.extern.slf4j.Slf4j;
import org.joda.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.http.RequestTimeout;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.user.UserVerifiedHost;
import ru.yandex.webmaster3.storage.user.UserUnverifiedHost;
import ru.yandex.webmaster3.storage.user.dao.UserLastVisitYDao;
import ru.yandex.webmaster3.storage.user.service.InitializedUsersService;
import ru.yandex.webmaster3.storage.user.service.UserHostsService;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.viewer.http.AbstractUserAction;

/**
 * @author aherman
 */
@Slf4j
@ReadAction
@Category("user")
@Description(value = "Возвращает информацию о пользователе.")
@RequestTimeout(11)
@Component("/user/info")
public class GetUserInfoAction extends AbstractUserAction<GetUserInfoRequest, GetUserInfoResponse> {
    private final UserHostsService userHostsService;
    private final UserLastVisitYDao userLastVisitYDao;
    private final InitializedUsersService initializedUsersService;

    @Autowired
    public GetUserInfoAction(UserHostsService userHostsService,
                             UserLastVisitYDao userLastVisitYDao,
                             InitializedUsersService initializedUsersService) {
        this.userHostsService = userHostsService;
        this.userLastVisitYDao = userLastVisitYDao;
        this.initializedUsersService = initializedUsersService;
    }

    @Override
    public GetUserInfoResponse process(GetUserInfoRequest request) throws WebmasterException {
        try {
            initializedUsersService.initializeUserIfNeeded(request.getUserId());
        } catch (WebmasterYdbException e) {
            throw new WebmasterException("Failed to get user initialization info",
                    new WebmasterErrorResponse.YDBErrorResponse(getClass(), e), e);
        }

        try {
            userLastVisitYDao.addVisit(request.getUserId(), Instant.now());
        } catch (WebmasterYdbException e) {
            log.warn("Failed to update user's last visit date", e);
        }

        List<UserVerifiedHost> verifiedHosts = userHostsService.getVerifiedHosts(request.getWebmasterUser());
        List<UserUnverifiedHost> unverifiedHosts = userHostsService.getMayBeUnverifiedHosts(request.getWebmasterUser());

        int verifiedHostsCount = verifiedHosts.size();
        int unverifiedHostsCount = 0;

        Set<WebmasterHostId> verifiedHostIdSet = new HashSet<>();
        for (UserVerifiedHost verifiedHost : verifiedHosts) {
            verifiedHostIdSet.add(verifiedHost.getWebmasterHostId());
        }
        for (UserUnverifiedHost unverifiedHost : unverifiedHosts) {
            if (!verifiedHostIdSet.contains(unverifiedHost.getWebmasterHostId())) {
                unverifiedHostsCount++;
            }
        }
        WebmasterHostId singleVerifiedHost = verifiedHosts.size() == 1 ? verifiedHosts.get(0).getWebmasterHostId() :
                null;
        return new GetUserInfoResponse.NormalResponse(verifiedHostsCount, unverifiedHostsCount, singleVerifiedHost);
    }
}
