/*
 * Copyright 2016-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.pcep.controller.impl;

import static org.onosproject.pcep.server.PcepLspSyncAction.SEND_UPDATE;
import static org.onosproject.pcep.server.PcepLspSyncAction.UNSTABLE;

import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelConfig;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelSubscription;
import org.onosproject.incubator.net.tunnel.Tunnel.Type;
import org.onosproject.net.Annotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Path;
import org.onosproject.pcep.server.ClientCapability;
import org.onosproject.pcep.server.PccId;
import org.onosproject.pcep.server.PcepEventListener;
import org.onosproject.pcep.server.PcepLspSyncAction;
import org.onosproject.pcep.server.PcepPacketStats;
import org.onosproject.pcep.server.PcepSyncStatus;
import org.onosproject.pcep.server.driver.PcepAgent;
import org.onosproject.pcep.server.impl.PcepClientControllerImpl;
import org.onosproject.pcep.server.impl.PcepClientImpl;
import org.onosproject.pcep.server.impl.PcepPacketStatsImpl;
import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepInitiateMsg;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepVersion;
import com.google.common.collect.ImmutableSet;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class PcepClientControllerImplTest {
    TestPcepClientControllerImpl controllerImpl = new TestPcepClientControllerImpl();
    TunnelService tunnelService = new MockTunnelService();
    private PcepEventListener listener;
    private Channel channel;

    @Before
    public void startUp() {
        controllerImpl.setTunnelService(tunnelService);
        listener = new PcepEventListenerAdapter();
        controllerImpl.addEventListener(listener);
        channel = new MockChannel();
    }

    @After
    public void tearDown() {
        controllerImpl.removeEventListener(listener);
        listener = null;
        controllerImpl.setTunnelService(null);
    }

    @Test
    public void tunnelProviderAddedTest1() throws PcepParseException, PcepOutOfBoundMessageException {
        PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));

        byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x50, 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0x00, 0x01, // SRP object
                                        0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
                                        0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x24, // LSP object
                                        0x00, 0x00, 0x10, (byte) 0xAB,
                                        0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path tlv
                                        0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
                                        0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05,
                                        0x05, 0x05, 0x05,

                                        0x07, 0x10, 0x00, 0x14, // ERO object
                                        0x01, 0x08, (byte) 0x01, 0x01, // ERO IPv4 sub objects
                                        0x01, 0x01, 0x04, 0x00,
                                        0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00, };

        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(reportMsg);

        PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
        PcepMessage message = reader.readFrom(buffer);

        PcepClientImpl pc = new PcepClientImpl();
        PcepPacketStats pktStats = new PcepPacketStatsImpl();

        pc.init(pccId, PcepVersion.PCEP_1, pktStats);
        pc.setChannel(channel);
        pc.setAgent(controllerImpl.agent());
        pc.setConnected(true);
        pc.setCapability(new ClientCapability(true, true, true, true, true));

        controllerImpl.agent().addConnectedClient(pccId, pc);
        controllerImpl.processClientMessage(pccId, message);

        pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
        pc.setLabelDbSyncStatus(PcepSyncStatus.IN_SYNC);
        pc.setLabelDbSyncStatus(PcepSyncStatus.SYNCED);

        List<PcepMessage> deleteMsgs = ((MockChannel) channel).msgsWritten();
        assertThat(deleteMsgs.size(), is(1));

        for (PcepMessage msg : deleteMsgs) {
            assertThat(((PcepInitiateMsg) msg).getPcInitiatedLspRequestList().getFirst().getSrpObject().getRFlag(),
                       is(true));
        }
    }

    @Test
    public void tunnelProviderAddedTest2() throws PcepParseException, PcepOutOfBoundMessageException {
        PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));

        byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x50, 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0x00, 0x01, // SRP object
                                        0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
                                        0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x24, 0x00, // LSP object
                                        0x00, 0x10, (byte) 0xAB,
                                        0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path tlv
                                        0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
                                        0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05,
                                        0x05, 0x05, 0x05,

                                        0x07, 0x10, 0x00, 0x14, // ERO object
                                        0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
                                        0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00, };

        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(reportMsg);

        PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
        PcepMessage message = reader.readFrom(buffer);

        PcepClientImpl pc = new PcepClientImpl();
        PcepPacketStats pktStats = new PcepPacketStatsImpl();

        pc.init(pccId, PcepVersion.PCEP_1, pktStats);
        pc.setChannel(channel);
        pc.setAgent(controllerImpl.agent());
        pc.setConnected(true);
        pc.setCapability(new ClientCapability(true, true, true, true, true));

        controllerImpl.agent().addConnectedClient(pccId, pc);
        controllerImpl.processClientMessage(pccId, message);

        pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
        pc.setLabelDbSyncStatus(PcepSyncStatus.IN_SYNC);
        pc.setLabelDbSyncStatus(PcepSyncStatus.SYNCED);
    }

    class PcepEventListenerAdapter implements PcepEventListener {

        public List<PcepMessage> handledMsg = new ArrayList<>();
        public List<Tunnel> tunnelsToBeUpdatedToNw = new ArrayList<>();
        public List<Tunnel> deletedFromNwTunnels = new ArrayList<>();

        @Override
        public void handleMessage(PccId pccId, PcepMessage msg) {
            handledMsg.add(msg);
        }

        @Override
        public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
            if (endOfSyncAction == SEND_UPDATE) {
                tunnelsToBeUpdatedToNw.add(tunnel);
                return;
            } else if (endOfSyncAction == UNSTABLE) {
                deletedFromNwTunnels.add(tunnel);
            }
        }
    }

    class MockChannel implements Channel {
        private List<PcepMessage> msgOnWire = new ArrayList<>();

        @Override
        public ChannelFuture write(Object o) {
            if (o instanceof List<?>) {
                @SuppressWarnings("unchecked")
                List<PcepMessage> msgs = (List<PcepMessage>) o;
                for (PcepMessage msg : msgs) {
                    if (msg instanceof PcepInitiateMsg) {
                        msgOnWire.add(msg);
                    }
                }
            }
            return null;
        }

        public List<PcepMessage> msgsWritten() {
            return msgOnWire;
        }

        @Override
        public int compareTo(Channel o) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public Integer getId() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFactory getFactory() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Channel getParent() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelConfig getConfig() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelPipeline getPipeline() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public boolean isOpen() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean isBound() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean isConnected() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public SocketAddress getLocalAddress() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SocketAddress getRemoteAddress() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture write(Object message, SocketAddress remoteAddress) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture bind(SocketAddress localAddress) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture connect(SocketAddress remoteAddress) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture disconnect() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture unbind() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture close() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture getCloseFuture() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int getInterestOps() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public boolean isReadable() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean isWritable() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public ChannelFuture setInterestOps(int interestOps) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ChannelFuture setReadable(boolean readable) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public boolean getUserDefinedWritability(int index) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void setUserDefinedWritability(int index, boolean isWritable) {
            // TODO Auto-generated method stub

        }

        @Override
        public Object getAttachment() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void setAttachment(Object attachment) {
            // TODO Auto-generated method stub

        }
    }

    class MockTunnelService implements TunnelService {
        private HashMap<TunnelId, Tunnel> tunnelIdAsKeyStore = new HashMap<TunnelId, Tunnel>();
        private int tunnelIdCounter = 0;

        @Override
        public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
            TunnelId tunnelId = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
            Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
                                                      tunnel.state(), tunnel.groupId(), tunnelId, tunnel.tunnelName(),
                                                      path, tunnel.annotations());
            tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
            return tunnelId;
        }

        @Override
        public Tunnel queryTunnel(TunnelId tunnelId) {
            for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
                if (tunnelIdKey.equals(tunnelId)) {
                    return tunnelIdAsKeyStore.get(tunnelId);
                }
            }
            return null;
        }

        @Override
        public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
            Collection<Tunnel> result = new HashSet<Tunnel>();
            Tunnel tunnel = null;
            for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
                tunnel = tunnelIdAsKeyStore.get(tunnelId);

                if ((null != tunnel) && (src.equals(tunnel.src())) && (dst.equals(tunnel.dst()))) {
                    result.add(tunnel);
                }
            }

            return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
        }

        @Override
        public Collection<Tunnel> queryTunnel(Tunnel.Type type) {
            Collection<Tunnel> result = new HashSet<Tunnel>();

            for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
                result.add(tunnelIdAsKeyStore.get(tunnelId));
            }

            return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
        }

        @Override
        public Collection<Tunnel> queryAllTunnels() {
            Collection<Tunnel> result = new HashSet<Tunnel>();

            for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
                result.add(tunnelIdAsKeyStore.get(tunnelId));
            }

            return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
        }

        @Override
        public void addListener(TunnelListener listener) {
            // TODO Auto-generated method stub

        }

        @Override
        public void removeListener(TunnelListener listener) {
            // TODO Auto-generated method stub

        }

        @Override
        public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelName tunnelName,
                                               Annotations... annotations) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
                                               Annotations... annotations) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
                                               Type type, Annotations... annotations) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName, Annotations... annotations) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst, Type type,
                                    Annotations... annotations) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
                                    Annotations... annotations) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int tunnelCount() {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
            // TODO Auto-generated method stub
            return null;
        }
    }

    private class TestPcepClientControllerImpl extends PcepClientControllerImpl {
        public void setTunnelService(TunnelService tunnelService) {
            this.tunnelService = tunnelService;
        }

        public PcepAgent agent() {
            return this.agent;
        }
    }
}
