package ru.yandex.webmaster3.internal.user.host.verification;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

import com.datastax.driver.core.utils.UUIDs;
import com.google.common.collect.Sets;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.data.WebmasterUser;
import ru.yandex.webmaster3.core.host.verification.UserHostVerificationInfo;
import ru.yandex.webmaster3.core.host.verification.VerificationCausedBy;
import ru.yandex.webmaster3.core.host.verification.VerificationType;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.RequestQueryProperty;
import ru.yandex.webmaster3.core.http.WriteAction;
import ru.yandex.webmaster3.core.user.UserVerifiedHost;
import ru.yandex.webmaster3.internal.common.InternalAction;
import ru.yandex.webmaster3.internal.common.InternalRequest;
import ru.yandex.webmaster3.internal.common.security.ActionInternalGrant;
import ru.yandex.webmaster3.internal.common.security.InternalGrant;
import ru.yandex.webmaster3.storage.user.dao.UserHostVerificationYDao;
import ru.yandex.webmaster3.storage.user.service.UserHostsService;
import ru.yandex.webmaster3.storage.verification.HostVerifierService;

@WriteAction
@Component("/user/host/verification/fake")
@Slf4j
@ActionInternalGrant(InternalGrant.HOST_VERIFICATION)
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class FakeVerificationAction extends InternalAction<FakeVerificationAction.FakeVerificationRequest, FakeVerificationAction.FakeVerificationResponse> {

    private final UserHostVerificationYDao userHostVerificationYDao;
    private final HostVerifierService hostVerifierService;
    private final UserHostsService userHostsService;
    @Value("${webmaster3.storage.yndxRobotWebmasterVrfr.id}")
    private final long yndxRobotFakeVerification;

    @Override
    public FakeVerificationResponse process(FakeVerificationRequest request) throws WebmasterException {

        log.info("got {} urls for fake verification ", request.getWebmasterHostIds().size());
        final Set<WebmasterHostId> verifiedHosts = userHostsService.getVerifiedHosts(new WebmasterUser(yndxRobotFakeVerification), request.webmasterHostIds)
                .stream()
                .map(UserVerifiedHost::getWebmasterHostId)
                .collect(Collectors.toSet());
        log.info("{} urls from {} already verified ", verifiedHosts.size(), request.getWebmasterHostIds().size());

        // добавляем хосты которые еще не добавлены
        UUID recordId = UUIDs.timeBased();
        Sets.difference(new HashSet<>(request.getWebmasterHostIds()), verifiedHosts).stream()
                .map(hostId -> UserHostVerificationInfo.createVerificationStartRecord(
                            recordId,
                            yndxRobotFakeVerification,
                            hostId,
                            VerificationType.FAKE,
                            ThreadLocalRandom.current().nextLong(),
                            VerificationCausedBy.INITIAL_VERIFICATION)
                )
        .forEach(verificationInfo -> {
            userHostVerificationYDao.addVerificationRecord(verificationInfo);
            hostVerifierService.verifyHost(yndxRobotFakeVerification, verificationInfo.getHostId(), recordId);
        });


        return new FakeVerificationResponse();
    }

    @Setter(onMethod_ = @RequestQueryProperty)
    @Getter
    public static class FakeVerificationRequest extends InternalRequest {
        private List<WebmasterHostId> webmasterHostIds;
    }

    public static class FakeVerificationResponse implements ActionResponse.NormalResponse {
    }
}
