package ru.yandex.webmaster3.storage.verification;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.host.verification.IUserHostVerifier;
import ru.yandex.webmaster3.core.host.verification.VerificationCausedBy;
import ru.yandex.webmaster3.core.host.verification.VerificationFailInfo;
import ru.yandex.webmaster3.core.host.verification.fail.SelfVerificationCancelled;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.storage.admin.SelfVerificationRecord;
import ru.yandex.webmaster3.storage.admin.UserRoleRecord;
import ru.yandex.webmaster3.storage.admin.dao.SelfHostVerificationsYDao;
import ru.yandex.webmaster3.storage.admin.dao.UserRolesYDao;
import ru.yandex.webmaster3.storage.admin.security.AccessActionEnum;
import ru.yandex.webmaster3.storage.admin.security.AccessObjectEnum;
import ru.yandex.webmaster3.storage.admin.security.Permission;
import ru.yandex.webmaster3.storage.admin.security.Role;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;

/**
 * @author avhaliullin
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class SelfVerifier implements IUserHostVerifier {
    private static final Permission SELF_VERIFICATION_PERMISSION = new Permission(AccessActionEnum.WRITE, AccessObjectEnum.HOST_SELF_VERIFICATION);

    private final SelfHostVerificationsYDao selfHostVerificationsYDao;
    private final UserRolesYDao userRolesYDao;

    @Override
    public Optional<VerificationFailInfo> verify(long userId, WebmasterHostId hostId, UUID recordId, long verificationUin, VerificationCausedBy verificationCausedBy) {
        try {
            SelfVerificationRecord verificationRecord = selfHostVerificationsYDao.getVerificationRecord(hostId, userId);
            if (verificationRecord == null) {
                return Optional.of(new SelfVerificationCancelled());
            }
            List<Role> roles = userRolesYDao.getUserRoles(verificationRecord.getAdminUserId())
                    .stream().map(UserRoleRecord::getRole).collect(Collectors.toList());
            for (Role role : roles) {
                if (role.getPermissions().contains(SELF_VERIFICATION_PERMISSION)) {
                    return Optional.empty();
                }
            }
            return Optional.of(new SelfVerificationCancelled());
        } catch (WebmasterYdbException e) {
            throw new WebmasterException("Failed to check self verification",
                    new WebmasterErrorResponse.YDBErrorResponse(getClass(), e), e);
        }
    }

    @Override
    public boolean isApplicable(WebmasterHostId hostId, long userId) {
        return true;
    }
}
