package net.f4fs.filesystem.util;

import java.util.HashSet;
import java.util.Set;

import net.f4fs.filesystem.P2PFS;
import net.f4fs.fspeer.FSPeer;
import net.tomp2p.dht.FutureGet;
import net.tomp2p.peers.Number160;


/**
 * Syncs the list of files in the FileSystem.
 * 
 * @author Reto
 */
public class FSFileSyncer
        implements Runnable {

    /**
     * List representing all fetched keys
     */
    private Set<String>  keys = new HashSet<>();

    /**
     * Filesystem to update its paths
     */
    private final P2PFS  _filesystem;

    /**
     * Peer of which to get a list of all stored
     * Paths in the P2P Network
     */
    private final FSPeer _peer;

    /**
     * Indicates whether this runnable is still running
     */
    private boolean      _isRunning;

    /**
     * Create a new Thread to "sync" the list of stored files
     * among the P2P network.
     * 
     * @param filesystem The filesystem to update
     * @param peer The peer from which to get the keys
     */
    public FSFileSyncer(P2PFS filesystem, FSPeer peer) {
        _filesystem = filesystem;
        _peer = peer;
        _isRunning = true;
    }

    /**
     * Terminates this runnable on the next iteration
     */
    public void terminate() {
        _isRunning = false;
    }

    @Override
    public void run() {
        while (_isRunning) {
            try {
                Set<String> localPaths = _filesystem.getAllPaths();
                keys = _peer.getAllPaths();

                // remove deleted files / dirs / symlinks / ...
                localPaths.removeAll(keys); // list of all localPaths which are removed in the DHT
                for (String pathToDelete : localPaths) {
                    _filesystem.unlink(pathToDelete);
                }

                // create local non-existing files
                for (String key : keys) {
                    if (_filesystem.getPath(key) == null) {
                        
                        // check whether the path is a link, that means key and target are different
                        FutureGet futureGet = _peer.getPath(Number160.createHash(key));
                        futureGet.await();
                        if (null != futureGet.data() && !key.equals((String) futureGet.data().object())) {
                            // target key is different from source key -> is a symlink
                            _filesystem.symlink((String) futureGet.data().object(), key);
                        } else {
                            _filesystem.create(key, null, null);
                        }
                    }
                }

                Thread.sleep(10000);
            } catch (Exception pEx) {
                pEx.printStackTrace();
                _isRunning = false;
            }
        }
    }
}

@@ -75,16 +75,49 @@
 til.Set;
+%0Aimport java.util.logging.Logger;
 %0A%0Aimport
@@ -376,16 +376,91 @@
 able %7B%0A%0A
+    private Logger       logger = Logger.getLogger(%22FSFileSyncer.class%22);%0A%0A
     /**%0A
@@ -539,16 +539,18 @@
 %3E  keys 
+  
 = new Ha
@@ -1599,301 +1599,8 @@
 );%0A%0A
-                // remove deleted files / dirs / symlinks / ...%0A                localPaths.removeAll(keys); // list of all localPaths which are removed in the DHT%0A                for (String pathToDelete : localPaths) %7B%0A                    _filesystem.unlink(pathToDelete);%0A                %7D%0A%0A
     
@@ -1752,33 +1752,9 @@
 ) %7B%0A
-                        
 %0A
+
     
@@ -2426,24 +2426,459 @@
          %7D%0A%0A
+                // remove deleted files / dirs / symlinks / ...%0A                localPaths.removeAll(keys); // list of all localPaths which are removed in the DHT%0A                for (String pathToDelete : localPaths) %7B%0A                    logger.info(%22Call removal of element on path '%22 + pathToDelete + %22'. LocalPaths: %22 + localPaths + %22, DHTPaths: %22 + keys);%0A                    _filesystem.unlink(pathToDelete);%0A                %7D%0A%0A
             
@@ -2898,17 +2898,16 @@
 eep(1000
-0
 );%0A     

Change order of removal > fetching all new paths