/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.provider.of.group.impl;

import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.GroupId;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.DriverServiceAdapter;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.group.DefaultGroupBucket;
import org.onosproject.net.group.Group;
import org.onosproject.net.group.GroupBucket;
import org.onosproject.net.group.GroupBuckets;
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupOperations;
import org.onosproject.net.group.GroupProvider;
import org.onosproject.net.group.GroupProviderRegistry;
import org.onosproject.net.group.GroupProviderService;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowClassifierListener;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowMessageListener;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PacketListener;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupMod;
import org.projectfloodlight.openflow.protocol.OFGroupModFailedCode;
import org.projectfloodlight.openflow.protocol.OFGroupStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupType;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFMeterFeatures;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.errormsg.OFGroupModFailedErrorMsg;
import org.projectfloodlight.openflow.types.OFGroup;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

import static org.junit.Assert.*;

public class OpenFlowGroupProviderTest {

    OpenFlowGroupProvider provider = new OpenFlowGroupProvider();
    private final OpenFlowController controller = new TestController();
    GroupProviderRegistry providerRegistry = new TestGroupProviderRegistry();
    GroupProviderService providerService;

    private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001");
    private Dpid dpid1 = Dpid.dpid(deviceId.uri());

    @Before
    public void setUp() {
        provider.controller = controller;
        provider.providerRegistry = providerRegistry;
        provider.cfgService = new ComponentConfigAdapter();
        provider.driverService = new DriverServiceAdapter();
        provider.activate(null);
    }

    @Test
    public void basics() {
        assertNotNull("registration expected", providerService);
        assertEquals("incorrect provider", provider, providerService.provider());
    }

    @Test
    public void addGroup() {

        GroupId groupId = new GroupId(1);

        List<GroupBucket> bucketList = Lists.newArrayList();
        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
        builder.setOutput(PortNumber.portNumber(1));
        GroupBucket bucket =
                DefaultGroupBucket.createSelectGroupBucket(builder.build());
        bucketList.add(bucket);
        GroupBuckets buckets = new GroupBuckets(bucketList);

        List<GroupOperation> operationList = Lists.newArrayList();
        GroupOperation operation = GroupOperation.createAddGroupOperation(groupId,
                GroupDescription.Type.SELECT, buckets);
        operationList.add(operation);
        GroupOperations operations = new GroupOperations(operationList);

        provider.performGroupOperation(deviceId, operations);

        final Dpid dpid = Dpid.dpid(deviceId.uri());
        TestOpenFlowSwitch sw = (TestOpenFlowSwitch) controller.getSwitch(dpid);
        assertNotNull("Switch should not be nul", sw);
        assertNotNull("OFGroupMsg should not be null", sw.msg);

    }


    @Test
    public void groupModFailure() {
        TestOpenFlowGroupProviderService testProviderService =
                (TestOpenFlowGroupProviderService) providerService;

        GroupId groupId = new GroupId(1);
        List<GroupBucket> bucketList = Lists.newArrayList();
        TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
        builder.setOutput(PortNumber.portNumber(1));
        GroupBucket bucket =
                DefaultGroupBucket.createSelectGroupBucket(builder.build());
        bucketList.add(bucket);
        GroupBuckets buckets = new GroupBuckets(bucketList);
        List<GroupOperation> operationList = Lists.newArrayList();
        GroupOperation operation = GroupOperation.createAddGroupOperation(groupId,
                GroupDescription.Type.SELECT, buckets);
        operationList.add(operation);
        GroupOperations operations = new GroupOperations(operationList);

        provider.performGroupOperation(deviceId, operations);

        OFGroupModFailedErrorMsg.Builder errorBuilder =
                OFFactories.getFactory(OFVersion.OF_13).errorMsgs().buildGroupModFailedErrorMsg();
        OFGroupMod.Builder groupBuilder = OFFactories.getFactory(OFVersion.OF_13).buildGroupModify();
        groupBuilder.setGroupType(OFGroupType.ALL);
        groupBuilder.setGroup(OFGroup.of(1));
        errorBuilder.setCode(OFGroupModFailedCode.GROUP_EXISTS);
        errorBuilder.setXid(provider.getXidAndAdd(0) - 1);

        controller.processPacket(dpid1, errorBuilder.build());

        assertNotNull("Operation failed should not be null",
                testProviderService.failedOperation);
    }


    @Test
    public void groupStatsEvent() {
        TestOpenFlowGroupProviderService testProviderService =
                (TestOpenFlowGroupProviderService) providerService;

        OFGroupStatsReply.Builder rep1 =
                OFFactories.getFactory(OFVersion.OF_13).buildGroupStatsReply();
        rep1.setXid(1);
        controller.processPacket(dpid1, rep1.build());
        OFGroupDescStatsReply.Builder rep2 =
                OFFactories.getFactory(OFVersion.OF_13).buildGroupDescStatsReply();
        assertNull("group entries is not set yet", testProviderService.getGroupEntries());

        rep2.setXid(2);
        controller.processPacket(dpid1, rep2.build());
        assertNotNull("group entries should be set", testProviderService.getGroupEntries());
    }


    @After
    public void tearDown() {
        provider.deactivate();
        provider.providerRegistry = null;
        provider.controller = null;
    }

    private class TestOpenFlowGroupProviderService
            extends AbstractProviderService<GroupProvider>
            implements GroupProviderService {

        Collection<Group> groups = null;
        GroupOperation failedOperation = null;

        protected TestOpenFlowGroupProviderService(GroupProvider provider) {
            super(provider);
        }

        @Override
        public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
            this.failedOperation = operation;
        }

        @Override
        public void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries) {
            this.groups = groupEntries;
        }

        @Override
        public void notifyOfFailovers(Collection<Group> groups) {
        }

        public Collection<Group> getGroupEntries() {
            return groups;
        }
    }

    private class TestController implements OpenFlowController {

        OpenFlowEventListener eventListener = null;
        List<OpenFlowSwitch> switches = Lists.newArrayList();

        public TestController() {
            OpenFlowSwitch testSwitch = new TestOpenFlowSwitch();
            switches.add(testSwitch);
        }

        @Override
        public void addListener(OpenFlowSwitchListener listener) {
        }

        @Override
        public void removeListener(OpenFlowSwitchListener listener) {

        }

        @Override
        public void addMessageListener(OpenFlowMessageListener listener) {

        }

        @Override
        public void removeMessageListener(OpenFlowMessageListener listener) {

        }

        @Override
        public void addPacketListener(int priority, PacketListener listener) {

        }

        @Override
        public void removePacketListener(PacketListener listener) {

        }

        @Override
        public void addEventListener(OpenFlowEventListener listener) {
            this.eventListener = listener;
        }

        @Override
        public void removeEventListener(OpenFlowEventListener listener) {

        }

        @Override
        public void write(Dpid dpid, OFMessage msg) {

        }

        @Override
        public CompletableFuture<OFMessage> writeResponse(Dpid dpid, OFMessage msg) {
            return null;
        }

        @Override
        public void processPacket(Dpid dpid, OFMessage msg) {
            eventListener.handleMessage(dpid, msg);
        }

        @Override
        public void setRole(Dpid dpid, RoleState role) {

        }

        @Override
        public Iterable<OpenFlowSwitch> getSwitches() {
            return switches;
        }

        @Override
        public Iterable<OpenFlowSwitch> getMasterSwitches() {
            return null;
        }

        @Override
        public Iterable<OpenFlowSwitch> getEqualSwitches() {
            return null;
        }

        @Override
        public OpenFlowSwitch getSwitch(Dpid dpid) {
            return switches.get(0);
        }

        @Override
        public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
            return null;
        }

        @Override
        public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
            return null;
        }

        @Override
        public void removeClassifierListener(OpenFlowClassifierListener listener) {
        }

        @Override
        public void addClassifierListener(OpenFlowClassifierListener listener) {
        }
    }

    private class TestGroupProviderRegistry implements GroupProviderRegistry {

        @Override
        public GroupProviderService register(GroupProvider provider) {
            providerService = new TestOpenFlowGroupProviderService(provider);
            return providerService;
        }

        @Override
        public void unregister(GroupProvider provider) {
        }

        @Override
        public Set<ProviderId> getProviders() {
            return null;
        }
    }

    private class TestOpenFlowSwitch implements OpenFlowSwitch {

        OFMessage msg = null;

        @Override
        public void sendMsg(OFMessage msg) {
            this.msg = msg;
        }

        @Override
        public void sendMsg(List<OFMessage> msgs) {

        }

        @Override
        public void handleMessage(OFMessage fromSwitch) {

        }

        @Override
        public void setRole(RoleState role) {

        }

        @Override
        public RoleState getRole() {
            return null;
        }

        @Override
        public List<OFPortDesc> getPorts() {
            return null;
        }

        @Override
        public OFMeterFeatures getMeterFeatures() {
            return null;
        }

        @Override
        public OFFactory factory() {
            return OFFactories.getFactory(OFVersion.OF_13);
        }

        @Override
        public String getStringId() {
            return null;
        }

        @Override
        public long getId() {
            return 0;
        }

        @Override
        public String manufacturerDescription() {
            return null;
        }

        @Override
        public String datapathDescription() {
            return null;
        }

        @Override
        public String hardwareDescription() {
            return null;
        }

        @Override
        public String softwareDescription() {
            return null;
        }

        @Override
        public String serialNumber() {
            return null;
        }

        @Override
        public boolean isConnected() {
            return false;
        }

        @Override
        public void disconnectSwitch() {

        }

        @Override
        public void returnRoleReply(RoleState requested, RoleState response) {

        }

        @Override
        public Device.Type deviceType() {
            return Device.Type.SWITCH;
        }

        @Override
        public String channelId() {
            return null;
        }
    }
}
