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

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.management.v1.processor.migration.Migration;
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Setter
@Service
public class V15ManualRedactionTypeRenameMigration extends Migration {

    @Autowired
    private FileStatusPersistenceService fileStatusPersistenceService;

    @Autowired
    private FileManagementStorageService fileManagementStorageService;

    @Autowired
    private ManualRedactionService manualRedactionService;


    public V15ManualRedactionTypeRenameMigration() {

        super(NAME, VERSION);
    }


    private static final String NAME = "Migrate ManualRedactionType names in EntityLog";
    private static final long VERSION = 15;


    @Override
    /*
     * Migrates the ManualRedactionType ADD_LOCALLY -> ADD, FORCE_REDACT -> FORCE, FORCE_HINT -> FORCE, REMOVE_LOCALLY -> REMOVE.
     */ protected void migrate() {

        log.info("Migrating ManualRedactionType names");

        Set<Class<? extends BaseAnnotation>> excludedClasses = Set.of(ManualResizeRedaction.class, ManualRecategorization.class, ManualLegalBasisChange.class);
        ManualChangesQueryOptions options = ManualChangesQueryOptions.builder().includeDictChanges(false).excludedClasses(excludedClasses).build();

        var files = fileStatusPersistenceService.getAllFiles();
        for (FileEntity file : files) {

            ManualRedactions manualChanges = manualRedactionService.getManualRedactions(file.getId(), options);

            if (manualChanges.isEmpty()) {
                continue;
            }

            if (!fileManagementStorageService.entityLogExists(file.getDossierId(), file.getId())) {
                continue;
            }

            log.info("Migrating ManualRedactionType names for fileId {}", file.getId());

            EntityLog entityLog = fileManagementStorageService.getEntityLog(file.getDossierId(), file.getId());
            for (EntityLogEntry entityLogEntry : entityLog.getEntityLogEntry()) {
                for (ManualChange manualChange : entityLogEntry.getManualChanges()) {
                    if (manualChange.getManualRedactionType().equals(ManualRedactionType.ADD_LOCALLY)) {
                        manualChange.setManualRedactionType(ManualRedactionType.ADD);
                    }
                    if (manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_REDACT)) {
                        manualChange.setManualRedactionType(ManualRedactionType.FORCE);
                    }
                    if (manualChange.getManualRedactionType().equals(ManualRedactionType.FORCE_HINT)) {
                        manualChange.setManualRedactionType(ManualRedactionType.FORCE);
                    }
                    if (manualChange.getManualRedactionType().equals(ManualRedactionType.REMOVE_LOCALLY)) {
                        manualChange.setManualRedactionType(ManualRedactionType.REMOVE);
                    }
                }
            }
            fileManagementStorageService.storeJSONObject(file.getDossierId(), file.getId(), FileType.ENTITY_LOG, entityLog);
        }

    }

}
