/*
 * Copyright 2017-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.opencord.igmpproxy.impl;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IGMP;
import org.onlab.packet.IGMPMembership;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.cluster.Leader;
import org.onosproject.cluster.Leadership;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.event.DefaultEventSinkRegistry;
import org.onosproject.event.Event;
import org.onosproject.event.EventDeliveryService;
import org.onosproject.event.EventSink;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.mcast.api.McastListener;
import org.onosproject.mcast.api.McastRoute;
import org.onosproject.mcast.api.McastRouteData;
import org.onosproject.mcast.api.MulticastRouteService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.config.basics.McastConfig;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.opencord.igmpproxy.IgmpLeadershipService;
import org.opencord.igmpproxy.impl.store.groupmember.AbstractGroupMemberStore;
import org.opencord.igmpproxy.impl.store.machine.AbstractStateMachineStore;
import org.opencord.igmpproxy.statemachine.StateMachine;
import org.opencord.igmpproxy.statemachine.StateMachineId;
import org.opencord.sadis.BandwidthProfileInformation;
import org.opencord.sadis.BaseInformationService;
import org.opencord.sadis.SadisService;
import org.opencord.sadis.SubscriberAndDeviceInformation;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.ComponentInstance;

import static com.google.common.base.Preconditions.checkState;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

public class IgmpManagerBase {

    // Device configuration
    protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:1");
    protected static final DeviceId DEVICE_ID_OF_B = DeviceId.deviceId("of:2");
    protected static final DeviceId DEVICE_ID_OF_C = DeviceId.deviceId("of:00000000000000003");

    //Multicast ip address
    protected static final Ip4Address GROUP_IP = Ip4Address.valueOf("224.0.0.0");
    //Unknown group Ip address
    protected static final Ip4Address UNKNOWN_GRP_IP = Ip4Address.valueOf("124.0.0.0");
    // Source ip address of two different device.
    protected static final Ip4Address SOURCE_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
    protected static final Ip4Address SOURCE_IP_OF_B = Ip4Address.valueOf("10.177.125.5");

    // Common connect point of aggregation switch used by all devices.
    protected static final ConnectPoint COMMON_CONNECT_POINT =
            ConnectPoint.deviceConnectPoint("of:00000000000000003/3");
    // Uplink ports for two olts A and B
    protected static final PortNumber PORT_A = PortNumber.portNumber(1);
    protected static final PortNumber PORT_B = PortNumber.portNumber(2);
    protected static final PortNumber PORT_C = PortNumber.portNumber(3);
    protected static final PortNumber PORT_NNI = PortNumber.portNumber(65536);

    // Connect Point mode for two olts
    protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
    protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_B, PORT_B);
    protected static final ConnectPoint CONNECT_POINT_C = new ConnectPoint(DEVICE_ID_OF_C, PORT_C);

    protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
    protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
    protected String dsBpId = "HSIA-DS";

    private static final int STATISTICS_GEN_PERIOD_IN_SEC = 2;

    private static final String NNI_PREFIX = "nni";

    protected List<Port> lsPorts = new ArrayList<Port>();
    protected List<Device> lsDevices = new ArrayList<Device>();
    // Flag for adding two different devices in oltData
    protected boolean flagForDevice = true;
    PacketContext context;
    // Flag for sending two different packets
    protected boolean flagForPacket = true;
    // Flag for sending two different packets
    protected boolean flagForQueryPacket = false;
    // Flag to check permission
    boolean flagForPermission = false;
    // List to store the packets emitted
    protected List<OutboundPacket> savedPackets;
    protected PacketProcessor packetProcessor;

    class MockDeviceService extends DeviceServiceAdapter {

        @Override
        public Device getDevice(DeviceId deviceId) {
            if (flagForDevice) {
                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                        .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
                SparseAnnotations annotations = annotationsBuilder.build();
                Annotations[] da = {annotations};
                Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "", "", "", null, da);
                flagForDevice = false;
                return deviceA;
            } else {
                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                        .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_B.toString());
                SparseAnnotations annotations = annotationsBuilder.build();
                Annotations[] da = {annotations};
                Device deviceB = new DefaultDevice(null, DEVICE_ID_OF_B, Device.Type.OTHER, "", "", "", "", null, da);
                return deviceB;
            }
        }

        @Override
        public List<Port> getPorts(DeviceId deviceId) {
            return lsPorts;
        }

        @Override
        public Iterable<Device> getAvailableDevices() {
            DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
            SparseAnnotations annotations = annotationsBuilder.build();
            Annotations[] da = {annotations};
            Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_C, Device.Type.OTHER, "", "", "", "", null, da);
            lsDevices.add(deviceA);
            return lsDevices;
        }

        @Override
        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
            if (portNumber.equals(PORT_NNI)) {
                DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                        .set(AnnotationKeys.PORT_NAME, NNI_PREFIX);
                Port nni = new DefaultPort(null, portNumber, true, annotationsBuilder.build());
                return nni;
            }
            return super.getPort(deviceId, portNumber);
        }
    }

    static final Class<IgmpproxyConfig> IGMPPROXY_CONFIG_CLASS = IgmpproxyConfig.class;
    static final Class<IgmpproxySsmTranslateConfig> IGMPPROXY_SSM_CONFIG_CLASS = IgmpproxySsmTranslateConfig.class;
    static final Class<McastConfig> MCAST_CONFIG_CLASS = McastConfig.class;
    ConfigFactory<ApplicationId, IgmpproxyConfig> igmpproxyConfigFactory =
            new ConfigFactory<ApplicationId, IgmpproxyConfig>(
                    SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_CONFIG_CLASS, "igmpproxy") {
                @Override
                public IgmpproxyConfig createConfig() {
                    return new IgmpproxyConfig();
                }
            };

    ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig> igmpproxySsmConfigFactory =
            new ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig>(
                    SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_SSM_CONFIG_CLASS, "ssmTranslate", true) {

                @Override
                public IgmpproxySsmTranslateConfig createConfig() {
                    return new IgmpproxySsmTranslateConfig();
                }
            };


    class MockIgmpProxyConfig extends IgmpproxyConfig {
        boolean igmpOnPodBasis = true;

        MockIgmpProxyConfig(boolean igmpFlagValue) {
            igmpOnPodBasis = igmpFlagValue;
        }

        @Override
        public boolean igmpOnPodBasis() {
            return igmpOnPodBasis;
        }

        @Override
        public ConnectPoint getSourceDeviceAndPort() {
            if (flagForPermission) {
                return null;
            }
            return COMMON_CONNECT_POINT;
        }

        @Override
        public ConnectPoint connectPoint() {
            return COMMON_CONNECT_POINT;
        }
    }


    class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
        Boolean igmpOnPodFlag = false;

        TestNetworkConfigRegistry(Boolean igmpFlag) {
            igmpOnPodFlag = igmpFlag;
        }

        @SuppressWarnings("unchecked")
        @Override
        public <S> Set<S> getSubjects(Class<S> subjectClass) {
            if (subjectClass.getName().equalsIgnoreCase("org.onosproject.net.DeviceId")) {
                return (Set<S>) ImmutableSet.of(DEVICE_ID_OF_A, DEVICE_ID_OF_B);
            }
            return null;
        }

        @SuppressWarnings("unchecked")
        @Override
        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
            if (configClass.getName().equalsIgnoreCase("org.opencord.igmpproxy.impl.IgmpproxyConfig")) {
                IgmpproxyConfig igmpproxyConfig = new MockIgmpProxyConfig(igmpOnPodFlag);
                return (C) igmpproxyConfig;
            } else {
                super.getConfig(subject, configClass);
            }
            return null;
        }
    }


    /**
     * Keeps a reference to the PacketProcessor and saves the OutboundPackets. Adds
     * the emitted packet in savedPackets list
     */
    class MockPacketService extends PacketServiceAdapter {

        public MockPacketService() {
            savedPackets = new LinkedList<>();
        }

        @Override
        public void addProcessor(PacketProcessor processor, int priority) {
            packetProcessor = processor;
        }

        @Override
        public void emit(OutboundPacket packet) {
            synchronized (savedPackets) {
                savedPackets.add(packet);
                savedPackets.notify();
            }
        }
    }

    class TestIgmpLeaderShipService implements IgmpLeadershipService {
        private NodeId nodeId = NodeId.nodeId("test-id");
        private Leader leader = new Leader(nodeId, 0, 0);
        private static final String TEST_TOPIC = "igmp-statistics";

        @Override
        public boolean isLocalLeader(DeviceId deviceId) {
            return true;
        }

        @Override
        public NodeId getLocalNodeId() {
            return nodeId;
        }

        @Override
        public NodeId getLeader(String topic) {
            return nodeId;
        }

        @Override
        public Leadership runForLeadership(String topic) {
            return new Leadership(TEST_TOPIC, leader, Lists.newArrayList(nodeId));
        }

        @Override
        public void withdraw(String topic) {

        }
    }

    class MockMastershipService extends MastershipServiceAdapter {
        @Override
        public boolean isLocalMaster(DeviceId deviceId) {
            return true;
        }
    }

    final class TestMulticastRouteService implements MulticastRouteService {
        @Override
        public void addListener(McastListener listener) {
        }

        @Override
        public void removeListener(McastListener listener) {
        }

        @Override
        public void add(McastRoute route) {
        }

        @Override
        public void remove(McastRoute route) {
        }

        @Override
        public Set<McastRoute> getRoutes() {
            return null;
        }

        @Override
        public Set<McastRoute> getRoute(IpAddress groupIp, IpAddress sourceIp) {
            return null;
        }

        @Override
        public void addSource(McastRoute route, HostId source) {
        }

        @Override
        public void addSources(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
        }

        @Override
        public void addSources(McastRoute route, Set<ConnectPoint> sources) {

        }

        @Override
        public void removeSources(McastRoute route) {

        }

        @Override
        public void removeSource(McastRoute route, HostId source) {

        }

        @Override
        public void removeSources(McastRoute route, Set<ConnectPoint> sources) {

        }

        @Override
        public void removeSources(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {

        }

        @Override
        public void addSink(McastRoute route, HostId hostId) {

        }

        @Override
        public void addSinks(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {

        }

        @Override
        public void addSinks(McastRoute route, Set<ConnectPoint> sinks) {

        }

        @Override
        public void removeSinks(McastRoute route) {

        }

        @Override
        public void removeSink(McastRoute route, HostId hostId) {

        }

        @Override
        public void removeSinks(McastRoute route, Set<ConnectPoint> sink) {

        }

        @Override
        public McastRouteData routeData(McastRoute route) {
            return null;
        }

        @Override
        public Set<ConnectPoint> sources(McastRoute route) {
            return null;
        }

        @Override
        public Set<ConnectPoint> sources(McastRoute route, HostId hostId) {
            return null;
        }

        @Override
        public Set<ConnectPoint> sinks(McastRoute route) {
            return null;
        }

        @Override
        public Set<ConnectPoint> sinks(McastRoute route, HostId hostId) {
            return null;
        }

        @Override
        public Set<ConnectPoint> nonHostSinks(McastRoute route) {
            return null;
        }

    }


    /**
     * Mocks the DefaultPacketContext.
     */
    final class TestPacketContext extends DefaultPacketContext {
        TestPacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
            super(time, inPkt, outPkt, block);
        }

        @Override
        public void send() {
            // We don't send anything out.
        }
    }

    /**
     * Sends Ethernet packet to the process method of the Packet Processor.
     *
     * @param reply Ethernet packet
     * @throws InterruptedException
     */
    void sendPacket(Ethernet reply) {

        if (reply != null) {
            final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());

            if (flagForQueryPacket) {
                InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_C, reply, byteBuffer);
                context = new TestPacketContext(127L, inBoundPacket, null, false);
                packetProcessor.process(context);
            } else {
                if (flagForPacket) {
                    InboundPacket inPacket = new DefaultInboundPacket(CONNECT_POINT_A, reply, byteBuffer);
                    context = new TestPacketContext(127L, inPacket, null, false);
                    flagForPacket = false;

                    packetProcessor.process(context);
                } else {
                    InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_B, reply, byteBuffer);
                    context = new TestPacketContext(127L, inBoundPacket, null, false);
                    flagForPacket = true;

                    packetProcessor.process(context);
                }
            }
        }
    }

    protected class MockSadisService implements SadisService {

        @Override
        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
            return new MockSubService();
        }

        @Override
        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
            return new MockBpService();
        }
    }

    private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {

        @Override
        public void clearLocalData() {

        }

        @Override
        public void invalidateAll() {

        }

        @Override
        public void invalidateId(String id) {

        }

        @Override
        public BandwidthProfileInformation get(String id) {
            if (id.equals(dsBpId)) {
                BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
                bpInfo.setAssuredInformationRate(0);
                bpInfo.setCommittedInformationRate(10000);
                bpInfo.setCommittedBurstSize(1000L);
                bpInfo.setExceededBurstSize(2000L);
                bpInfo.setExceededInformationRate(20000);
                return bpInfo;
            }
            return null;
        }

        @Override
        public BandwidthProfileInformation getfromCache(String id) {
            return null;
        }
    }

    private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
        MockSubscriberAndDeviceInformation sub =
                new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID,
                        CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);

        @Override
        public SubscriberAndDeviceInformation get(String id) {
            return sub;
        }

        @Override
        public void clearLocalData() {

        }

        @Override
        public void invalidateAll() {
        }

        @Override
        public void invalidateId(String id) {
        }

        @Override
        public SubscriberAndDeviceInformation getfromCache(String id) {
            return null;
        }
    }

    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {

        MockSubscriberAndDeviceInformation(String id, String nasPortId,
                                           String circuitId, MacAddress hardId,
                                           Ip4Address ipAddress) {
            this.setHardwareIdentifier(hardId);
            this.setId(id);
            this.setIPAddress(ipAddress);
            this.setNasPortId(nasPortId);
            this.setCircuitId(circuitId);
            this.setUplinkPort((int) PORT_NNI.toLong());
        }
    }

    protected class MockCfgService implements ComponentConfigService {

        @Override
        public Set<String> getComponentNames() {
            return null;
        }

        @Override
        public void registerProperties(Class<?> componentClass) {

        }

        @Override
        public void unregisterProperties(Class<?> componentClass, boolean clear) {

        }

        @Override
        public Set<ConfigProperty> getProperties(String componentName) {
            return null;
        }

        @Override
        public void setProperty(String componentName, String name, String value) {

        }

        @Override
        public void preSetProperty(String componentName, String name, String value) {

        }

        @Override
        public void preSetProperty(String componentName, String name, String value, boolean override) {

        }

        @Override
        public void unsetProperty(String componentName, String name) {

        }

        @Override
        public ConfigProperty getProperty(String componentName, String attribute) {
            return null;
        }

    }

    public static class TestEventDispatcher extends DefaultEventSinkRegistry implements EventDeliveryService {

        @Override
        @SuppressWarnings("unchecked")
        public synchronized void post(Event event) {
            EventSink sink = getSink(event.getClass());
            checkState(sink != null, "No sink for event %s", event);
            sink.process(event);
        }

        @Override
        public void setDispatchTimeLimit(long millis) {
        }

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

    class MockComponentContext implements ComponentContext {

        @Override
        public Dictionary<String, Object> getProperties() {
            Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
            cfgDict.put("statisticsGenerationPeriodInSeconds", STATISTICS_GEN_PERIOD_IN_SEC);
            return cfgDict;
        }

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

        @Override
        public Object locateService(String name, ServiceReference reference) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object[] locateServices(String name) {
            // TODO Auto-generated method stub
            return null;
        }

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

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

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

        @Override
        public void enableComponent(String name) {
            // TODO Auto-generated method stub
        }

        @Override
        public void disableComponent(String name) {
            // TODO Auto-generated method stub
        }

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

    Ethernet buildWrongIgmpPacket(Ip4Address groupIp, Ip4Address sourceIp) {
        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
        igmpMembership.setRecordType((byte) 0x33);

        return IgmpSender.getInstance().buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp,
                igmpMembership, sourceIp, false, VlanId.ANY_VALUE, VlanId.NO_VID, IgmpSender.DEFAULT_COS);
    }

    Ethernet buildUnknownIgmpPacket(Ip4Address groupIp, Ip4Address sourceIp) {
        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
        igmpMembership.setRecordType((byte) 0x33);

        return IgmpSender.getInstance().buildIgmpPacket((byte) 0x44, groupIp, igmpMembership, sourceIp, false,
                VlanId.ANY_VALUE, VlanId.NO_VID, IgmpSender.DEFAULT_COS);
    }

    class TestStateMachineStoreService extends AbstractStateMachineStore {
        private static final int DEFAULT_COUNT = 0;
        private Map<StateMachineId, AtomicLong> countsMap;

        public TestStateMachineStoreService(Map<StateMachineId, StateMachine> map) {
            super();
            stateMachineMap = Maps.newConcurrentMap();
            countsMap = Maps.newConcurrentMap();
        }

        @Override
        public long increaseAndGetCounter(StateMachineId stateMachineId) {
            AtomicLong count = countsMap.get(stateMachineId);
            if (count == null) {
                count = new AtomicLong(DEFAULT_COUNT);
                countsMap.put(stateMachineId, count);
            }
            return count.incrementAndGet();
        }

        @Override
        public long decreaseAndGetCounter(StateMachineId stateMachineId) {
            AtomicLong count = countsMap.get(stateMachineId);
            if (count.get() > 0) {
                return count.decrementAndGet();
            } else {
                return count.get();
            }
        }

        @Override
        public boolean removeCounter(StateMachineId stateMachineId) {
            countsMap.remove(stateMachineId);
            return true;
        }

        @Override
        public long getCounter(StateMachineId stateMachineId) {
            return countsMap.get(stateMachineId).get();
        }

    }


    class TestGroupMemberStoreService extends AbstractGroupMemberStore {
        public TestGroupMemberStoreService() {
            super(Maps.newConcurrentMap());
        }
    }
}
