/*
 * This file is part of Bisq.
 *
 * Bisq is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * Bisq is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Bisq. If not, see <http://www.gnu.org/licenses/>.
 */

package bisq.core.network.p2p.seed;

import bisq.core.app.BisqEnvironment;

import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.seed.SeedNodeRepository;

import javax.inject.Inject;
import javax.inject.Named;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.annotation.Nullable;

public class DefaultSeedNodeRepository implements SeedNodeRepository {
    //TODO add support for localhost addresses
    private static final Pattern pattern = Pattern.compile("^([a-z0-9]+\\.onion:\\d+)");
    private static final String ENDING = ".seednodes";
    private static final Collection<NodeAddress> cache = new HashSet<>();
    private final BisqEnvironment bisqEnvironment;
    private final String seedNodes;

    @Inject
    public DefaultSeedNodeRepository(BisqEnvironment environment,
                                     @Nullable @Named(NetworkOptionKeys.SEED_NODES_KEY) String seedNodes) {
        bisqEnvironment = environment;
        this.seedNodes = seedNodes;
    }

    private void reload() {

        // see if there are any seed nodes configured manually
        if (seedNodes != null && !seedNodes.isEmpty()) {
            cache.clear();
            Arrays.stream(seedNodes.split(",")).forEach(s -> cache.add(new NodeAddress(s)));

            return;
        }

        // else, we fetch the seed nodes from our resources
        final InputStream fileInputStream = DefaultSeedNodeRepository.class.getClassLoader().getResourceAsStream(BisqEnvironment.getBaseCurrencyNetwork().name().toLowerCase() + ENDING);
        final BufferedReader seedNodeFile = new BufferedReader(new InputStreamReader(fileInputStream));

        // only clear if we have a fresh data source (otherwise, an exception would prevent us from getting here)
        cache.clear();

        // refill the cache
        seedNodeFile.lines().forEach(line -> {
            final Matcher matcher = pattern.matcher(line);
            if (matcher.find())
                cache.add(new NodeAddress(matcher.group(1)));

            // Maybe better include in regex...
            if (line.startsWith("localhost"))
                cache.add(new NodeAddress(line));
        });

        // filter
        cache.removeAll(bisqEnvironment.getBannedSeedNodes().stream().map(NodeAddress::new).collect(Collectors.toSet()));
    }

    public Collection<NodeAddress> getSeedNodeAddresses() {
        if (cache.isEmpty())
            reload();

        return cache;
    }

    public boolean isSeedNode(NodeAddress nodeAddress) {
        if (cache.isEmpty())
            reload();
        return cache.contains(nodeAddress);
    }
}

@@ -1219,35 +1219,174 @@
 ort 
-javax.annotation.Nullable;%0A
+lombok.extern.slf4j.Slf4j;%0A%0Aimport javax.annotation.Nullable;%0A%0A// If a new BaseCurrencyNetwork type gets added we need to add the resource file for it as well!%0A@Slf4j
 %0Apub
@@ -1765,24 +1765,38 @@
 nvironment;%0A
+    @Nullable%0A
     private 
@@ -2116,25 +2116,41 @@
 oad() %7B%0A
-%0A
+        try %7B%0A   
         
 // see i
@@ -2141,16 +2141,17 @@
         
+ 
 // see i
@@ -2201,24 +2201,28 @@
 lly%0A        
+    
 if (seedNode
@@ -2262,32 +2262,36 @@
 ) %7B%0A            
+   
+ 
 cache.clear();%0A 
@@ -2285,24 +2285,28 @@
 he.clear();%0A
+    
             
@@ -2395,24 +2395,28 @@
             
+  
+  
 return;%0A    
@@ -2415,27 +2415,35 @@
 rn;%0A        
-%7D%0A%0A
+    %7D%0A%0A    
         // e
@@ -2498,21 +2498,19 @@
         
-final
+   
  InputSt
@@ -2682,21 +2682,19 @@
         
-final
+   
  Buffere
@@ -2773,24 +2773,28 @@
 tStream));%0A%0A
+    
         // o
@@ -2895,32 +2895,36 @@
 g here)%0A        
+    
 cache.clear();%0A%0A
@@ -2919,24 +2919,28 @@
 e.clear();%0A%0A
+    
         // r
@@ -2963,16 +2963,20 @@
         
+    
 seedNode
@@ -3018,16 +3018,20 @@
         
+   
+ 
 final Ma
@@ -3077,24 +3077,28 @@
             
+    
 if (matcher.
@@ -3113,32 +3113,36 @@
                 
+   
+ 
 cache.add(new No
@@ -3184,16 +3184,20 @@
         
+    
 // Maybe
@@ -3232,24 +3232,28 @@
             
+  
+  
 if (line.sta
@@ -3274,16 +3274,20 @@
 host%22))%0A
+    
         
@@ -3340,13 +3340,21 @@
     
+  
+  
 %7D);%0A%0A
+    
     
@@ -3371,24 +3371,28 @@
 ter%0A        
+ 
+   
 cache.remove
@@ -3489,24 +3489,157 @@
 .toSet()));%0A
+        %7D catch (Throwable t) %7B%0A            log.error(t.toString());%0A            t.printStackTrace();%0A            throw t;%0A        %7D%0A
     %7D%0A%0A    p

Add try/catch to print error in case the file does not exist