package net.floodlightcontroller.staticflowentry;


/*
public class StaticFlowTests extends FloodlightTestCase {    
    
    static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
    static int TotalTestRules = 3;
    
    //
    // Create TestRuleXXX and the corresponding FlowModXXX
    // for X = 1..3
    //
    static Map<String,Object> TestRule1;
    static OFFlowMod FlowMod1;
    static {
        FlowMod1 = new OFFlowMod();
        TestRule1 = new HashMap<String,Object>();
        TestRule1.put(COLUMN_NAME, "TestRule1");
        TestRule1.put(COLUMN_SWITCH, TestSwitch1DPID);
        // setup match
        OFMatch match = new OFMatch();
        TestRule1.put(COLUMN_DL_DST, "00:20:30:40:50:60");
        match.fromString("dl_dst=00:20:30:40:50:60");
        // setup actions
        List<OFAction> actions = new LinkedList<OFAction>();
        TestRule1.put(COLUMN_ACTIONS, "output=1");
        actions.add(new OFActionOutput((short)1, (short) Short.MAX_VALUE));
        // done
        FlowMod1.setMatch(match);
        FlowMod1.setActions(actions);
        FlowMod1.setBufferId(-1);
        FlowMod1.setOutPort(OFPort.OFPP_NONE.getValue());
        FlowMod1.setPriority(Short.MAX_VALUE);
        FlowMod1.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions
    }
    
    static Map<String,Object> TestRule2;
    static OFFlowMod FlowMod2;

    static {
        FlowMod2 = new OFFlowMod();
        TestRule2 = new HashMap<String,Object>();
        TestRule2.put(COLUMN_NAME, "TestRule2");
        TestRule2.put(COLUMN_SWITCH, TestSwitch1DPID);
        // setup match
        OFMatch match = new OFMatch();
        TestRule2.put(COLUMN_NW_DST, "192.168.1.0/24");
        match.fromString("nw_dst=192.168.1.0/24");
        // setup actions
        List<OFAction> actions = new LinkedList<OFAction>();
        TestRule2.put(COLUMN_ACTIONS, "output=1");
        actions.add(new OFActionOutput((short)1, (short) Short.MAX_VALUE));
        // done
        FlowMod2.setMatch(match);
        FlowMod2.setActions(actions);
        FlowMod2.setBufferId(-1);
        FlowMod2.setOutPort(OFPort.OFPP_NONE.getValue());
        FlowMod2.setPriority(Short.MAX_VALUE);
        FlowMod2.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions

    }
    
   
    static Map<String,Object> TestRule3;
    static OFFlowMod FlowMod3;
    static {
        FlowMod3 = new OFFlowMod();
        TestRule3 = new HashMap<String,Object>();
        TestRule3.put(COLUMN_NAME, "TestRule3");
        TestRule3.put(COLUMN_SWITCH, TestSwitch1DPID);
        // setup match
        OFMatch match = new OFMatch();
        TestRule3.put(COLUMN_DL_DST, "00:20:30:40:50:60");
        TestRule3.put(COLUMN_DL_VLAN, 4096);
        match.fromString("dl_dst=00:20:30:40:50:60,dl_vlan=4096");
        // setup actions
        TestRule3.put(COLUMN_ACTIONS, "output=controller");
        List<OFAction> actions = new LinkedList<OFAction>();
        actions.add(new OFActionOutput(OFPort.OFPP_CONTROLLER.getValue(), (short) Short.MAX_VALUE));
        // done
        FlowMod3.setMatch(match);
        FlowMod3.setActions(actions);
        FlowMod3.setBufferId(-1);
        FlowMod3.setOutPort(OFPort.OFPP_NONE.getValue());
        FlowMod3.setPriority(Short.MAX_VALUE);
        FlowMod3.setLengthU(OFFlowMod.MINIMUM_LENGTH + 8);  // 8 bytes of actions

    }
    
    private void verifyFlowMod(OFFlowMod testFlowMod,
            OFFlowMod goodFlowMod) {
        verifyMatch(testFlowMod, goodFlowMod);
        verifyActions(testFlowMod, goodFlowMod);
        // dont' bother testing the cookie; just copy it over
        goodFlowMod.setCookie(testFlowMod.getCookie());
        // .. so we can continue to use .equals()
        assertEquals(goodFlowMod, testFlowMod);
    }
    

    private void verifyMatch(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) {
        assertEquals(goodFlowMod.getMatch(), testFlowMod.getMatch());
    }


    private void verifyActions(OFFlowMod testFlowMod, OFFlowMod goodFlowMod) {
        List<OFAction> goodActions = goodFlowMod.getActions();
        List<OFAction> testActions = testFlowMod.getActions();
        assertNotNull(goodActions);
        assertNotNull(testActions);
        assertEquals(goodActions.size(), testActions.size());
        // assumes actions are marshalled in same order; should be safe
        for(int i = 0; i < goodActions.size(); i++) {
            assertEquals(goodActions.get(i), testActions.get(i));
        }

    }


    @Override 
    public void setUp() throws Exception {
        super.setUp();
    }
    
    @Test
    public void testStaticFlowPush() throws IOException {        
        StaticFlowEntryPusher staticFlowEntryPusher = new StaticFlowEntryPusher();
        IStorageSourceService storage = createStorageWithFlowEntries();
        long dpid = HexString.toLong(TestSwitch1DPID);

        // Create a Switch and attach a switch
        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
        Capture<OFMessage> writeCapture = new Capture<OFMessage>(CaptureType.ALL);
        Capture<FloodlightContext> contextCapture = new Capture<FloodlightContext>(CaptureType.ALL);
        Capture<List<OFMessage>> writeCaptureList = new Capture<List<OFMessage>>(CaptureType.ALL);

        //OFMessageSafeOutStream mockOutStream = createNiceMock(OFMessageSafeOutStream.class);
        mockSwitch.write(capture(writeCapture), capture(contextCapture));
        expectLastCall().anyTimes();
        mockSwitch.write(capture(writeCaptureList), capture(contextCapture));
        expectLastCall().anyTimes();
        mockSwitch.flush();
        expectLastCall().anyTimes();
        
        staticFlowEntryPusher.setStorageSource(storage);
        
        FloodlightModuleContext fmc = new FloodlightModuleContext();
        
        MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
        Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>();
        switchMap.put(dpid, mockSwitch);
        // NO ! expect(mockFloodlightProvider.getSwitches()).andReturn(switchMap).anyTimes();
        mockFloodlightProvider.setSwitches(switchMap);
        staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider);
        RestApiServer restApi = new RestApiServer();
        try {
            restApi.init(fmc);
        } catch (FloodlightModuleException e) {
            e.printStackTrace();
        }
        staticFlowEntryPusher.restApi = restApi;
        staticFlowEntryPusher.startUp(null);    // again, to hack unittest

        // verify that flowpusher read all three entries from storage
        assertEquals(TotalTestRules, staticFlowEntryPusher.countEntries());
        
        // if someone calls mockSwitch.getOutputStream(), return mockOutStream instead
        //expect(mockSwitch.getOutputStream()).andReturn(mockOutStream).anyTimes();    

        // if someone calls getId(), return this dpid instead
        expect(mockSwitch.getId()).andReturn(dpid).anyTimes();
        expect(mockSwitch.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
        replay(mockSwitch);
        
        // hook the static pusher up to the fake switch
        staticFlowEntryPusher.addedSwitch(mockSwitch);
        
        verify(mockSwitch);
        
        // Verify that the switch has gotten some flow_mods
        assertEquals(true, writeCapture.hasCaptured());
        assertEquals(TotalTestRules, writeCapture.getValues().size());
        
        // Order assumes how things are stored in hash bucket; 
        // should be fixed because OFMessage.hashCode() is deterministic
        OFFlowMod firstFlowMod = (OFFlowMod) writeCapture.getValues().get(2);
        verifyFlowMod(firstFlowMod, FlowMod1);
        OFFlowMod secondFlowMod = (OFFlowMod) writeCapture.getValues().get(1);
        verifyFlowMod(secondFlowMod, FlowMod2);
        OFFlowMod thirdFlowMod = (OFFlowMod) writeCapture.getValues().get(0);
        verifyFlowMod(thirdFlowMod, FlowMod3);
        
        writeCapture.reset();
        contextCapture.reset();
        
        
        // delete two rules and verify they've been removed
        // this should invoke staticFlowPusher.rowsDeleted()
        storage.deleteRow(StaticFlowEntryPusher.TABLE_NAME, "TestRule1");
        storage.deleteRow(StaticFlowEntryPusher.TABLE_NAME, "TestRule2");

        assertEquals(1, staticFlowEntryPusher.countEntries());
        assertEquals(2, writeCapture.getValues().size());
        
        OFFlowMod firstDelete = (OFFlowMod) writeCapture.getValues().get(0);
        FlowMod1.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
        verifyFlowMod(firstDelete, FlowMod1);

        OFFlowMod secondDelete = (OFFlowMod) writeCapture.getValues().get(1);
        FlowMod2.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
        verifyFlowMod(secondDelete, FlowMod2);
        
        // add rules back to make sure that staticFlowPusher.rowsInserted() works
        writeCapture.reset();
        FlowMod2.setCommand(OFFlowMod.OFPFC_ADD);
        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule2);
        assertEquals(2, staticFlowEntryPusher.countEntries());
        assertEquals(1, writeCaptureList.getValues().size());
        List<OFMessage> outList = 
            (List<OFMessage>) writeCaptureList.getValues().get(0);
        assertEquals(1, outList.size());
        OFFlowMod firstAdd = (OFFlowMod) outList.get(0);
        verifyFlowMod(firstAdd, FlowMod2);
        writeCapture.reset();
        contextCapture.reset();
        writeCaptureList.reset();
        
        // now try an update, calling staticFlowPusher.rowUpdated()
        TestRule3.put(COLUMN_DL_VLAN, 333);
        storage.updateRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3);
        assertEquals(2, staticFlowEntryPusher.countEntries());
        assertEquals(1, writeCaptureList.getValues().size());

        outList = (List<OFMessage>) writeCaptureList.getValues().get(0);
        assertEquals(2, outList.size());
        OFFlowMod removeFlowMod = (OFFlowMod) outList.get(0);
        FlowMod3.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
        verifyFlowMod(removeFlowMod, FlowMod3);
        FlowMod3.setCommand(OFFlowMod.OFPFC_ADD);
        FlowMod3.getMatch().fromString("dl_dst=00:20:30:40:50:60,dl_vlan=333");
        OFFlowMod updateFlowMod = (OFFlowMod) outList.get(1);
        verifyFlowMod(updateFlowMod, FlowMod3);

    }


    IStorageSourceService createStorageWithFlowEntries() {
        return populateStorageWithFlowEntries(new MemoryStorageSource());
    }
    
    IStorageSourceService populateStorageWithFlowEntries(IStorageSourceService storage) {
        Set<String> indexedColumns = new HashSet<String>();
        indexedColumns.add(COLUMN_NAME);
        storage.createTable(StaticFlowEntryPusher.TABLE_NAME, indexedColumns);
        storage.setTablePrimaryKeyName(StaticFlowEntryPusher.TABLE_NAME, COLUMN_NAME);

        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule1);
        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule2);
        storage.insertRow(StaticFlowEntryPusher.TABLE_NAME, TestRule3);

        return storage;
    }
    
    @Test 
    public void testHARoleChanged() throws IOException {
        StaticFlowEntryPusher staticFlowEntryPusher = new StaticFlowEntryPusher();
        IStorageSourceService storage = createStorageWithFlowEntries();
        MockFloodlightProvider mfp = getMockFloodlightProvider();
        staticFlowEntryPusher.setFloodlightProvider(mfp);
        staticFlowEntryPusher.setStorageSource(storage);
        RestApiServer restApi = new RestApiServer();
        try {
            FloodlightModuleContext fmc = new FloodlightModuleContext();
            restApi.init(fmc);
        } catch (FloodlightModuleException e) {
            e.printStackTrace();
        }
        staticFlowEntryPusher.restApi = restApi;
        staticFlowEntryPusher.startUp(null);    // again, to hack unittest
        
        assert(staticFlowEntryPusher.entry2dpid.containsValue(TestSwitch1DPID));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod1));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod2));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod3));
        
        // Send a notification that we've changed to slave
        mfp.dispatchRoleChanged(null, Role.SLAVE);
        // Make sure we've removed all our entries
        assert(staticFlowEntryPusher.entry2dpid.isEmpty());
        assert(staticFlowEntryPusher.entriesFromStorage.isEmpty());
        
        // Send a notification that we've changed to master
        mfp.dispatchRoleChanged(Role.SLAVE, Role.MASTER);  
        // Make sure we've learned the entries
        assert(staticFlowEntryPusher.entry2dpid.containsValue(TestSwitch1DPID));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod1));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod2));
        assert(staticFlowEntryPusher.entriesFromStorage.containsValue(FlowMod3));
    }
}
*/
