package com.iqser.red.service.persistence.management.v1.processor.service;

import java.util.HashSet;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient;
import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User;
import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService;
import com.iqser.red.service.persistence.management.v1.processor.utils.TenantUtils;
import com.knecon.fforesight.tenantcommons.TenantContext;
import com.knecon.fforesight.tenantcommons.TenantProvider;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class KeyCloakUserSyncService {

    private final UserService userService;
    private final UsersClient usersClient;
    private final DossierManagementService dossierManagementService;
    private final DossierACLService dossierACLService;
    private final TenantProvider tenantProvider;


    public void syncUsersWithKC() {
        tenantProvider.getTenants().forEach(tenant -> {

            if(!TenantUtils.isTenantReadyForPersistence(tenant)){
                return;
            }

            TenantContext.setTenantId(tenant.getTenantId());

            var allUsers = usersClient.getAllUsers(true);
            // all userIds from KC
            var allUserIds = allUsers.stream().map(User::getUserId).collect(Collectors.toSet());

            var redactionObjectsUserIds = new HashSet<String>();

            var alLDossiers = dossierManagementService.getAllDossiers(true, true);
            // find all userIds that are used by redaction
            alLDossiers.forEach(dossier -> {
                dossierACLService.enhanceDossierWithACLData(dossier);
                redactionObjectsUserIds.addAll(dossier.getMemberIds());
            });

            // remove KC users, what's left is users that are in redaction but no longer in KC
            redactionObjectsUserIds.removeAll(allUserIds);

            log.info("Performing user sync/cleanup for ids: {}", redactionObjectsUserIds);

            redactionObjectsUserIds.forEach(removedUser -> alLDossiers.forEach(dossier -> this.userService.updateDossierUsers(removedUser,
                    UserService.UserRemovalModel.PERMANENT,
                    dossier)));

            TenantContext.clear();
        });

    }

}
