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

import java.io.InputStream;

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

import com.iqser.red.service.persistence.management.v1.processor.migration.Migration;
import com.iqser.red.service.persistence.management.v1.processor.migration.migrations.model.reducetext.Text;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;

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

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

    private static final String NAME = "Reduce TEXT filesize migration";
    private static final long VERSION = 10;

    @Autowired
    private DossierPersistenceService dossierPersistenceService;

    @Autowired
    private FileStatusPersistenceService fileStatusPersistenceService;

    @Autowired
    private StorageService storageService;

    @Autowired
    private FileManagementStorageService fileManagementStorageService;


    public ReduceTextFileSizeMigration10() {

        super(NAME, VERSION);
    }


    @Override
    protected void migrate() {

        var dossiers = dossierPersistenceService.findAllDossiers();
        dossiers.forEach(dossier -> {
            if (dossier.getHardDeletedTime() == null) {
                var files = fileStatusPersistenceService.getStatusesForDossier(dossier.getId());
                log.info("Start migration of dossier {}", dossier.getId());
                files.forEach(file -> {
                    if (file.getHardDeletedTime() == null) {
                        log.info("Start migration of file {}", file.getId());
                        migrateFile(dossier.getId(), file.getId());
                        log.info("Finished migration of file {}", file.getId());
                    }
                });
                log.info("Finished migration of dossier {}", dossier.getId());
            }
        });

        log.info("All files are migrated, removing bak files");

        dossiers.forEach(dossier -> {
            if (dossier.getHardDeletedTime() == null) {
                var files = fileStatusPersistenceService.getStatusesForDossier(dossier.getId());
                log.info("Start removing bak files of dossier {}", dossier.getId());
                files.forEach(file -> {
                    if (file.getHardDeletedTime() == null) {
                        log.info("Start removing bak of file {}", file.getId());
                        storageService.deleteObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossier.getId(), file.getId(), FileType.TEXT) + ".bak");
                        log.info("Finished removing bak of file {}", file.getId());
                    }
                });
                log.info("Finished removing bak files of dossier {}", dossier.getId());
            }
        });

        log.info("All bak files removed");

    }


    @SneakyThrows
    public void migrateFile(String dossierId, String fileId) {

        try {

            if (!storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.TEXT) + ".bak")) {
                InputStream textInputStreamResource = fileManagementStorageService.getObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.TEXT));
                storageService.storeObject(TenantContext.getTenantId(),
                        StorageIdUtils.getStorageId(dossierId, fileId, FileType.TEXT) + ".bak",
                        textInputStreamResource);
                textInputStreamResource.close();
                var text = storageService.readJSONObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.TEXT), Text.class);
                storageService.storeJSONObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.TEXT), text);
            }
        } catch (StorageObjectDoesNotExist e) {
            log.warn("Text not found for dossier {} and file {}, ignoring....", dossierId, fileId);
        }
    }

}





