package zmo.technology.lite.components;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import zmo.technology.lite.core.ZeroCoreStructs;
import zmo.technology.lite.core.ZeroFolders;
import zmo.technology.lite.core.ZeroFolders.ZeroFolderContainer;
import zmo.technology.lite.core.ZeroFolders.ZeroFolderEntity;
import zmo.technology.lite.core.ZeroProcessor;
import zmo.technology.lite.core.ZeroRequestGuider;
import zmo.technology.lite.processors.ZeroFolderProcessor;

public class ZeroFolderComponent extends ZeroProcessor {
    
    protected ZeroFolderComponent(ZeroRequestGuider guider) {
        super(guider);
    }

    public static ZeroFolderComponent build(ZeroRequestGuider guider) {
        return new ZeroFolderComponent(guider);
    }

    private ZeroFolderProcessor folderProcessor;

    public ZeroFolderProcessor folderProcessor() {
        if (folderProcessor == null)
            folderProcessor = ZeroFolderProcessor.build(guider);
        return folderProcessor;
    }

    public void reference(String refEntityID, String refDataID, String refDirectory) throws SQLException {
        ZeroFolderEntity entity = folderProcessor().fetchFolderInfo(refEntityID);
        entity.setRelevancyID(refDataID);
        entity.setDirectory(refDirectory);
        String[] dirs = refDirectory.split("/");
        List<String> paths = new ArrayList<>();
        for (String dir : dirs)
            if (!dir.trim().isEmpty())
                paths.add(dir);
        paths.add(refEntityID);
        entity.setPath(String.join("/", paths));
        folderProcessor().addRelevancyFolder(entity);
    }

    public void save(ZeroCoreStructs structs) throws Exception {
        if (structs.getFolders() == null)
            return;
        for (Map.Entry<String, ZeroFolderContainer> entry : structs.getFolders().entrySet()) {
            for (ZeroFolderEntity entity : entry.getValue().getEntities()) {
                if (entity.getFeatures().containsKey(ZeroFolders.ZERO_FOLDER_ENTITY_TICKET)) {
                    long refCount = folderProcessor().fetchDataRefCount(structs.uuIDString(), entry.getKey());
                    long i = refCount - entry.getValue().getMaxLimit() + 1;
                    for (; i > 0; i--)
                        folderProcessor().rmLastDataRef(structs.uuIDString(), entry.getKey());
                    reference(entity.getFeatures().getString(ZeroFolders.ZERO_FOLDER_ENTITY_TICKET),
                            structs.uuIDString(), entry.getKey());
                }
            }
        }
    }

    public void clean(ZeroCoreStructs structs) throws Exception {
        List<ZeroFolderEntity> entities = folderProcessor().fetchDataRef(structs.uuIDString());
        for (ZeroFolderEntity entity : entities)
            folderProcessor().rmFolder(entity);
    }

    public void fetch(ZeroCoreStructs structs) throws Exception {
        List<ZeroFolderEntity> entities = folderProcessor().fetchDataRef(structs.uuIDString());
        structs.initFolders();
        for (ZeroFolderEntity entity : entities)
            structs.getFolders().get(entity.getDirectory()).addEntity(entity);
    }
}
