package net.tomp2p.p2p;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import net.tomp2p.Utils2;
import net.tomp2p.futures.BaseFuture;
import net.tomp2p.futures.FutureAnnounce;
import net.tomp2p.futures.FuturePing;
import net.tomp2p.peers.Number160;

import org.junit.Assert;
import org.junit.Test;

public class TestAnnounce {
	/**
	 * Start with -Djava.net.preferIPv4Stack=true
	 * @throws Exception
	 */
	@Test
    public void testLocalAnnounce() throws Exception {
        final Random rnd = new Random(42);
        Peer master = null;
        try {
            // setup
            Peer[] peers = Utils2.createNonMaintenanceNodes(100, rnd, 4001);
            master = peers[0];
            // do testing
            List<FutureAnnounce> tmp = new ArrayList<FutureAnnounce>();
            // we start from 1, because a broadcast to ourself will not get
            // replied.
            for (int i = 1; i < peers.length; i++) {
                FutureAnnounce res = peers[i].localAnnounce().port(4001).start();
                tmp.add(res);
            }
            for(FutureAnnounce f:tmp) {
            	f.awaitUninterruptibly();
            }
            //check the local map
            for(int i=0;i<peers.length;i++) {
            	Peer peer = peers[i];
            	int size = peer.peerBean().localMap().size();
            	if(i == 0) {
            		int counter = 0;
            		while(size < 99 && counter < 20) {
            			Thread.sleep(100);
            			size = peer.peerBean().localMap().size();
            			counter ++;
            		}
            		Assert.assertEquals(99, size);
            	} else {
            		Assert.assertEquals(0, size);
            	}
            }
        } finally {
            if (master != null) {
                master.shutdown().await();
            }
        }
    }

	/**
	 * Start with -Djava.net.preferIPv4Stack=true
	 * @throws Exception
	 */
    @Test
    public void testLocalAnnounceTranslate() throws Exception {
        final Random rnd = new Random(42);
        Peer master = null;
        Peer slave = null;
        try {
            master = new PeerBuilder(new Number160(rnd)).ports(4001).start();
            slave = new PeerBuilder(new Number160(rnd)).ports(4002).start();
            BaseFuture res = slave.localAnnounce().port(4001).start();
            res.awaitUninterruptibly();
            System.err.println(res.failedReason());
            Assert.assertEquals(true, res.isSuccess());
            
            int size = master.peerBean().localMap().size();
            int counter = 0;
    		while(size < 1 && counter < 20) {
    			Thread.sleep(100);
    			size = master.peerBean().localMap().size();
    			counter ++;
    		}
    		Assert.assertEquals(1, size);
    		//1.2.3.4 gets rewritten
    		FuturePing fp = master.ping().peerAddress(slave.peerAddress().changeAddress(InetAddress.getByName("1.2.3.4"))).start();
    		fp.awaitUninterruptibly();
    		Assert.assertEquals(true, fp.isSuccess());
    		Assert.assertEquals(InetAddress.getByName("1.2.3.4"), fp.remotePeer().inetAddress());
        } finally {
            if (master != null) {
                master.shutdown().await();
            }
            if (slave != null) {
                slave.shutdown().await();
            }
        }
    }
}

@@ -71,24 +71,53 @@
 .ArrayList;%0A
+import java.util.Collection;%0A
 import java.
@@ -123,24 +123,24 @@
 .util.List;%0A
-
 import java.
@@ -179,16 +179,62 @@
 Utils2;%0A
+import net.tomp2p.connection.DiscoverResults;%0A
 import n
@@ -811,16 +811,98 @@
 ers%5B0%5D;%0A
+            if(!hasBroadcastAddress(master)) %7B%0A            %09return;%0A            %7D%0A
         
@@ -2457,32 +2457,113 @@
 (4002).start();%0A
+            if(!hasBroadcastAddress(slave)) %7B%0A            %09return;%0A            %7D%0A
             Base
@@ -3570,32 +3570,32 @@
 ;%0A            %7D%0A
-
         %7D%0A    %7D%0A
@@ -3594,10 +3594,353 @@
 %7D%0A    %7D%0A
+    %0A    private boolean hasBroadcastAddress(Peer peer) %7B%0A    %09final DiscoverResults discoverResults = peer.connectionBean().channelServer().discoverNetworks().currentDiscoverResults();%0A        final Collection%3CInetAddress%3E broadcastAddresses = discoverResults.existingBroadcastAddresses();%0A        return broadcastAddresses.size() %3E 0;%0A    %7D%0A
 %7D%0A

disable broadcasting test if no interface found