package org.asteriskjava.manager.internal.backwardsCompatibility.bridge;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.asteriskjava.manager.event.BridgeCreateEvent;
import org.asteriskjava.manager.event.BridgeDestroyEvent;
import org.asteriskjava.manager.event.BridgeEnterEvent;
import org.asteriskjava.manager.event.BridgeEvent;
import org.asteriskjava.manager.event.BridgeLeaveEvent;
import org.asteriskjava.manager.event.ManagerEvent;
import org.asteriskjava.util.Log;
import org.asteriskjava.util.LogFactory;

/**
 * Track the current members of a bridge, emmitting BridgeEvents when 2 members
 * join or breakup
 * 
 * @author rsutton
 */
public class BridgeState
{
    final Log logger = LogFactory.getLog(getClass());

    BridgeCreateEvent created;
    BridgeDestroyEvent destroyed;
    private final Map<String, BridgeEnterEvent> members = new ConcurrentHashMap<>();

    public BridgeState(BridgeCreateEvent event)
    {
        created = event;
    }

    public ManagerEvent destroy(BridgeDestroyEvent event)
    {
        destroyed = event;
        return null;

    }

    /**
     * if there are exactly 2 members in the bridge, return a BridgeEvent
     * 
     * @param event
     * @return
     */
    public ManagerEvent addMember(BridgeEnterEvent event)
    {
        final String channel = event.getChannel();
        members.put(event.getChannel(), event);
        logger.info("Members size " + members.size() + " " + event);
        if (members.size() == 2)
        {
            BridgeEvent bridgeEvent = new BridgeEvent(this);

            List<BridgeEnterEvent> memberList = new LinkedList<>();
            memberList.addAll(members.values());
            bridgeEvent.setCallerId1(memberList.get(0).getCallerIdNum());
            bridgeEvent.setCallerId2(memberList.get(1).getCallerIdNum());
            bridgeEvent.setUniqueId1(memberList.get(0).getUniqueId());
            bridgeEvent.setUniqueId2(memberList.get(1).getUniqueId());
            bridgeEvent.setChannel1(memberList.get(0).getChannel());
            bridgeEvent.setChannel2(memberList.get(1).getChannel());
            bridgeEvent.setBridgeState(BridgeEvent.BRIDGE_STATE_LINK);
            bridgeEvent.setDateReceived(new Date());

            logger.info("Bridge " + bridgeEvent.getChannel1() + " " + bridgeEvent.getChannel2());

            return bridgeEvent;
        }
        return null;

    }

    /**
     * If there are exactly 2 members in the bridge, return a BridgeEvent
     * 
     * @param event
     * @return
     */

    public ManagerEvent removeMember(BridgeLeaveEvent event)
    {
        for (BridgeEnterEvent member : members.values())
        {
            if (member.getChannel().equalsIgnoreCase(event.getChannel()) && members.size() == 2)
            {
                BridgeEvent bridgeEvent = new BridgeEvent(this);

                List<BridgeEnterEvent> memberList = new LinkedList<>();
                memberList.addAll(members.values());

                bridgeEvent.setCallerId1(memberList.get(0).getCallerIdNum());
                bridgeEvent.setCallerId2(memberList.get(1).getCallerIdNum());
                bridgeEvent.setUniqueId1(memberList.get(0).getUniqueId());
                bridgeEvent.setUniqueId2(memberList.get(1).getUniqueId());
                bridgeEvent.setChannel1(memberList.get(0).getChannel());
                bridgeEvent.setChannel2(memberList.get(1).getChannel());
                bridgeEvent.setBridgeState(BridgeEvent.BRIDGE_STATE_UNLINK);
                bridgeEvent.setDateReceived(new Date());

                members.remove(member.getChannel());

                return bridgeEvent;

            }
        }

        return null;
    }

}

@@ -1556,117 +1556,8 @@
 t);%0A
-        if (members.size() == 2)%0A        %7B%0A            BridgeEvent bridgeEvent = new BridgeEvent(this);%0A%0A    
     
@@ -1616,36 +1616,32 @@
 st%3C%3E();%0A        
-  
-  
 memberList.addAl
@@ -1657,24 +1657,132 @@
 .values());%0A
+        if (memberList.size() == 2)%0A        %7B%0A            BridgeEvent bridgeEvent = new BridgeEvent(this);%0A%0A
             
@@ -2685,32 +2685,72 @@
 nt event)%0A    %7B%0A
+        BridgeEvent bridgeEvent = null;%0A
         for (Bri
@@ -2876,112 +2876,23 @@
 l())
- && members.size() == 2)%0A            %7B%0A                BridgeEvent bridgeEvent = new BridgeEvent(this);%0A
+)%0A            %7B
 %0A   
@@ -3009,25 +3009,149 @@
 .values());%0A
-%0A
+                if (memberList.size() == 2)%0A                %7B%0A%0A                    bridgeEvent = new BridgeEvent(this);%0A%0A    
             
@@ -3208,32 +3208,36 @@
 CallerIdNum());%0A
+    
                 
@@ -3306,32 +3306,36 @@
                 
+ 
+   
 bridgeEvent.setU
@@ -3369,32 +3369,36 @@
 getUniqueId());%0A
+    
                 
@@ -3464,32 +3464,36 @@
                 
+ 
+   
 bridgeEvent.setC
@@ -3525,32 +3525,36 @@
 .getChannel());%0A
+    
                 
@@ -3618,32 +3618,36 @@
                 
+ 
+   
 bridgeEvent.setB
@@ -3699,32 +3699,36 @@
                 
+    
 bridgeEvent.setD
@@ -3744,32 +3744,49 @@
 ed(new Date());%0A
+                %7D
 %0A               
@@ -3901,20 +3901,27 @@
  return 
-null
+bridgeEvent
 ;%0A    %7D%0A

fix for BridgeState