/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.openflow.controller.impl;

import org.junit.Before;
import org.junit.Test;
import org.onosproject.openflow.ExecutorServiceAdapter;
import org.onosproject.openflow.MockOfFeaturesReply;
import org.onosproject.openflow.MockOfPacketIn;
import org.onosproject.openflow.MockOfPortStatus;
import org.onosproject.openflow.OfMessageAdapter;
import org.onosproject.openflow.OpenFlowSwitchListenerAdapter;
import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowPacketContext;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.PacketListener;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import static junit.framework.TestCase.fail;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

/**
 * Tests for packet processing in the open flow controller impl class.
 */
public class OpenFlowControllerImplPacketsTest {
    OpenFlowControllerImpl controller;
    OpenFlowControllerImpl.OpenFlowSwitchAgent agent;
    Dpid dpid1;
    OpenFlowSwitch switch1;
    OpenFlowSwitchListenerAdapter switchListener;
    TestPacketListener packetListener;
    TestExecutorService statsExecutorService;
    TestExecutorService pktInExecutorService;
    TestExecutorService flowRmvExecutorService;

    /**
     * Mock packet listener that accumulates packets.
     */
    class TestPacketListener implements PacketListener {
        List<OpenFlowPacketContext> contexts = new ArrayList<>();

        @Override
        public void handlePacket(OpenFlowPacketContext pktCtx) {
            contexts.add(pktCtx);
        }

        List<OpenFlowPacketContext> contexts() {
            return contexts;
        }
    }


    /**
     * Mock executor service that tracks submits.
     */
    static class TestExecutorService extends ExecutorServiceAdapter {
        private List<OFMessage> submittedMessages = new ArrayList<>();

        List<OFMessage> submittedMessages() {
            return submittedMessages;
        }

        @Override
        public void execute(Runnable task) {
            OpenFlowControllerImpl.OFMessageHandler handler =
                    (OpenFlowControllerImpl.OFMessageHandler) task;
            submittedMessages.add(handler.msg);
        }
    }

    /**
     * Sets up switches to use as data, mocks and launches a controller instance.
     */
    @Before
    public void setUp() {
        try {
            switch1 = new OpenflowSwitchDriverAdapter();
            dpid1 = Dpid.dpid(new URI("of:0000000000000111"));
        } catch (URISyntaxException ex) {
            //  Does not happen
            fail();
        }

        controller = new OpenFlowControllerImpl();
        agent = controller.agent;
        switchListener = new OpenFlowSwitchListenerAdapter();
        controller.addListener(switchListener);
        controller.monitorAllEvents(true);

        packetListener = new TestPacketListener();
        controller.addPacketListener(100, packetListener);

        statsExecutorService = new TestExecutorService();
        pktInExecutorService = new TestExecutorService();
        flowRmvExecutorService = new TestExecutorService();

        controller.executorMsgs = statsExecutorService;
        controller.executorPacketIn = pktInExecutorService;
        controller.executorFlowRemoved = flowRmvExecutorService;

    }

    /**
     * Tests a port status operation.
     */
    @Test
    public void testPortStatus() {
        OFMessage portStatusPacket = new MockOfPortStatus();
        controller.processPacket(dpid1, portStatusPacket);
        assertThat(switchListener.portChangedDpids().size(), is(1));
        assertThat(switchListener.portChangedDpids().containsKey(dpid1),
                   is(true));
        assertThat(switchListener.portChangedDpids().get(dpid1),
                   equalTo(portStatusPacket));
    }

    /**
     * Tests a features reply operation.
     */
    @Test
    public void testFeaturesReply() {
        OFMessage ofFeaturesReplyPacket = new MockOfFeaturesReply();
        controller.processPacket(dpid1, ofFeaturesReplyPacket);
        assertThat(switchListener.changedDpids(), hasSize(1));
        assertThat(switchListener.changedDpids().get(0),
                   equalTo(dpid1));
    }

    /**
     * Tests a packet in listen operation.
     */
    @Test
    public void testPacketInListen() {
        agent.addConnectedSwitch(dpid1, switch1);
        OFMessage packetInPacket = new MockOfPacketIn();
        controller.processPacket(dpid1, packetInPacket);
        assertThat(packetListener.contexts(), hasSize(1));
        assertThat(pktInExecutorService.submittedMessages(), hasSize(1));
        assertThat(pktInExecutorService.submittedMessages().get(0), is(packetInPacket));
    }

    /**
     * Tests an error operation.
     */
    @Test
    public void testError() {
        agent.addConnectedSwitch(dpid1, switch1);
        OfMessageAdapter errorPacket = new OfMessageAdapter(OFType.ERROR);
        controller.processPacket(dpid1, errorPacket);
        assertThat(statsExecutorService.submittedMessages(), hasSize(1));
        assertThat(statsExecutorService.submittedMessages().get(0), is(errorPacket));
    }

    /**
     * Tests a packet in operation.
     */
    @Test
    public void testFlowRemoved() {
        agent.addConnectedSwitch(dpid1, switch1);
        OFMessage flowRemovedPacket = new MockOfFlowRemoved();
        controller.processPacket(dpid1, flowRemovedPacket);
        assertThat(flowRmvExecutorService.submittedMessages(), hasSize(1));
        assertThat(flowRmvExecutorService.submittedMessages().get(0), is(flowRemovedPacket));
    }
}
