package ru.yandex.wmconsole.servantlet.api;

import java.util.ArrayList;
import java.util.Collection;
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.webmaster.common.host.HostListService;
import ru.yandex.wmconsole.authorization.ApiOAuthPermission;
import ru.yandex.wmconsole.data.info.FastHostInfo;
import ru.yandex.wmconsole.data.info.api.ApiHostInfo;
import ru.yandex.wmconsole.data.wrappers.api.ApiHostInfoWrapper;
import ru.yandex.wmconsole.service.FastHostListService;
import ru.yandex.wmconsole.viewer.api.ApiHostNodeInfo;
import ru.yandex.wmconsole.viewer.api.ApiVersion;
import ru.yandex.wmconsole.viewer.api.wrappers.ApiHostNodeInfoWrapper;
import ru.yandex.webmaster.common.host.HostNodeInfo;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.error.InternalProblem;
import ru.yandex.wmtools.common.util.XmlConvertableCollectionWrapper;

public class ApiHostListServantlet extends AbstractApiServantlet {

    private static final String TAG_HOST_LIST = "hostlist";

    private FastHostListService fastHostListService;
    private HostListService hostListService;

    @Override
    public void apiDoProcess(ServRequest req, ServResponse res, long userId) throws InternalException {
        String apiVersionStr = req.getParam(ApiVersion.API_VERSION_PARAM, ApiVersion.V1.name());
        ApiVersion apiVersion = ApiVersion.valueOf(apiVersionStr);
        if (apiVersion == ApiVersion.V1 ||
                apiVersion == ApiVersion.V2) {
            processV2(res, userId);
        } else if (apiVersion == ApiVersion.V3) {
            processV3(res, userId);
        }
    }

    private void processV2(ServResponse res, long userId) throws InternalException {
        Collection<FastHostInfo> hostInfos = fastHostListService.getFastHostList(null, userId, true, true);
        List<ApiHostInfo> oauthHostInfos = new ArrayList<ApiHostInfo>();
        for (FastHostInfo info : hostInfos) {
            if ((info.getUrls() != null) && (info.getUrls() > 0) &&
                    ((info.getTcy() == null) || (info.getIndexCount() == null))) {//todo (minor) move it to FastHostListService?
                throw new InternalException(InternalProblem.PROCESSING_ERROR, "not enough data");
            }

            oauthHostInfos.add(new ApiHostInfo(info.getId(), info.getName(), info.getVerificationState(),
                    info.getVerificationType(), info.getUrls(), info.isVirused(), info.getTcy(), info.getIndexCount(),
                    info.getHostInfoStatus(), info.getLastAccess()));
        }

        res.addData(XmlConvertableCollectionWrapper.wrap(oauthHostInfos, ApiHostInfoWrapper.class, TAG_HOST_LIST));
    }

    private void processV3(ServResponse res, long userId) throws InternalException {
        List<HostNodeInfo> hostNodes = hostListService.getHostList(userId, null);
        List<ApiHostNodeInfo> oauthHostInfos = new ArrayList<>(hostNodes.size());
        for (HostNodeInfo hostNodeInfo : hostNodes) {
            oauthHostInfos.add(new ApiHostNodeInfo(hostNodeInfo));
        }
        res.addData(XmlConvertableCollectionWrapper.wrap(oauthHostInfos, ApiHostNodeInfoWrapper.class, TAG_HOST_LIST));
    }

    @Override
    public ApiOAuthPermission getRequiredPermission() {
        return ApiOAuthPermission.COMMON_OPERATIONS;
    }

    @Required
    public void setFastHostListService(FastHostListService fastHostListService) {
        this.fastHostListService = fastHostListService;
    }

    @Required
    public void setHostListService(HostListService hostListService) {
        this.hostListService = hostListService;
    }
}
