package usda.weru.remoteDataAccess.csip;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import usda.weru.remoteDataAccess.RdaHierarchicalItem;
import usda.weru.remoteDataAccess.RdaInputController;
import usda.weru.remoteDataAccess.RdaInputControllerCacheLoader;
import usda.weru.remoteDataAccess.exceptions.RdaConnectException;

/**
 *
 * @author mhaas
 */
public class CsipInputControllerCacheLoader extends RdaInputControllerCacheLoader {

    Logger LOGGER = LogManager.getLogger(CsipInputControllerCacheLoader.class);

    public CsipInputControllerCacheLoader(RdaInputController controllerCache, CsipInputControllerCachingSupport cacheSupport) {
        super(controllerCache, cacheSupport);
    }

    @Override
    protected boolean backgroundTraverseCacheFiles(RdaHierarchicalItem dataTree, File idxFile, boolean skip, File skipRefFile) {
//        for (RdaHierarchicalItem fileItem : dataTree.getChildren()) {
        ArrayList<RdaHierarchicalItem> children = dataTree.getChildren();
        for (RdaHierarchicalItem fileItem : children) {
            if (fileItem.isFile()) {
                File cacheFile = ((CsipInputControllerCachingSupport) cachingSupport).getFileFromParsedItem(fileItem, baseCacheDir);
                if (skip) {
                    // short pause while skipping
                    // so we go quickly but still allow app to be useable
                    try {
                        Thread.sleep(bgPauseLengthShort);
                    } catch (InterruptedException ex) {
                    }
                    if (cacheFile.equals(skipRefFile)) {
                        skip = false;
                    }
                } else {
                    // Longer pause when actually downloading.
                    // there are multiple CSIP services, so there will ikely be multiple of these
                    //  background threads running at same time.
                    try {
                        Thread.sleep(bgPauseLengthLong);
                    } catch (InterruptedException ex) {
                    }

                    System.out.println(" caching:" + cacheFile);
                    try {
                        cacheSingleFile(fileItem, cacheFile, idxFile);
                    } catch (IOException ex) {
                        LOGGER.log(Level.INFO,
                                "Background load {0} failed to write cache file: {1}", new Object[]{interfaceName, cacheFile.getAbsolutePath()});
                        System.err.println(
                                "Background load " + interfaceName
                                + " failed to write cache file: " + cacheFile.getAbsolutePath());

                        // After deleting the failed fileitem,
                        // this for loop is out of sync and will throw an error.
                        // so start the call over with the updated dataTree.
                        dataTree.deleteChild(fileItem);
                    } catch (RdaConnectException ex) {
                        LOGGER.log(Level.INFO,
                                "Background load {0} failed to fetch file: {1}", new Object[]{interfaceName, cacheFile.getAbsolutePath()});
                        System.err.println(
                                "Background load " + interfaceName
                                + " failed to fetch file: " + cacheFile.getAbsolutePath());

                        dataTree.deleteChild(fileItem);
                        // After deleting the failed fileitem,
                        // this for loop is out of sync and will throw an error.
                        // so start the call over with the updated dataTree.
                        return backgroundTraverseCacheFiles(dataTree, idxFile, skip, skipRefFile);
                    }
                }
            } else {
                skip = backgroundTraverseCacheFiles(fileItem, idxFile, skip, skipRefFile);
            }
        }
        return skip;
    }

    protected void cacheSingleFile(RdaHierarchicalItem fileItem, File cacheFile, File idxFile) throws RdaConnectException, IOException {
        cacheFile.getParentFile().mkdirs();
        rdaControllerCache.controllerSetDestinationPath(cacheFile.getParentFile().toPath());
        File csipFile = doCallCsipGetRecord(fileItem.getName(), fileItem.getParentPath());
//        writeIdxFile (idxFile, csipFile.getAbsolutePath());
        appendIdxFile(idxFile, csipFile.getAbsolutePath());
        cachingSupport.cacheAddToCatalog(fileItem.getParentPath() + "\\" + fileItem.getName());

    }

    protected File doCallCsipGetRecord(String name, String parentPath) throws RdaConnectException {
        return ((CsipInterface) rdaInterface).callCsipGetRecord(name, parentPath);
    }
}
