/*
 * 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.onosproject.vpls;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.TestApplicationId;
import org.onosproject.cluster.LeadershipEvent;
import org.onosproject.cluster.LeadershipEventListener;
import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultHost;
import org.onosproject.net.DeviceId;
import org.onosproject.net.EncapsulationType;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigServiceAdapter;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostServiceAdapter;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentServiceAdapter;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.StoreDelegate;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vpls.api.Vpls;
import org.onosproject.vpls.api.VplsData;
import org.onosproject.vpls.config.VplsAppConfig;
import org.onosproject.vpls.config.VplsAppConfigTest;
import org.onosproject.vpls.config.VplsConfig;
import org.onosproject.vpls.store.VplsStoreAdapter;
import org.onosproject.vpls.store.VplsStoreEvent;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Class provides data for VPLS testing.
 */
public abstract class VplsTest {
    protected static final String APP_NAME = "org.onosproject.vpls";
    protected static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
    protected static final String DASH = "-";
    protected static final int PRIORITY_OFFSET = 1000;
    protected static final String VPLS1 = "vpls1";
    protected static final String VPLS2 = "vpls2";
    protected static final String VPLS3 = "vpls3";
    protected static final String VPLS4 = "vpls4";

    protected static final PortNumber P1 = PortNumber.portNumber(1);
    protected static final PortNumber P2 = PortNumber.portNumber(2);

    protected static final DeviceId DID1 = getDeviceId(1);
    protected static final DeviceId DID2 = getDeviceId(2);
    protected static final DeviceId DID3 = getDeviceId(3);
    protected static final DeviceId DID4 = getDeviceId(4);
    protected static final DeviceId DID5 = getDeviceId(5);
    protected static final DeviceId DID6 = getDeviceId(6);

    protected static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
    protected static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
    protected static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
    protected static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
    protected static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
    protected static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
    protected static final ConnectPoint CP7 = new ConnectPoint(DID4, P2);
    protected static final ConnectPoint CP8 = new ConnectPoint(DID3, P2);
    protected static final ConnectPoint CP9 = new ConnectPoint(DID5, P1);
    protected static final ConnectPoint CP10 = new ConnectPoint(DID5, P2);

    protected static final VlanId VLAN100 = VlanId.vlanId((short) 100);
    protected static final VlanId VLAN200 = VlanId.vlanId((short) 200);
    protected static final VlanId VLAN300 = VlanId.vlanId((short) 300);
    protected static final VlanId VLAN400 = VlanId.vlanId((short) 400);
    protected static final VlanId VLAN_NONE = VlanId.NONE;

    protected static final MacAddress MAC1 = getMac(1);
    protected static final MacAddress MAC2 = getMac(2);
    protected static final MacAddress MAC3 = getMac(3);
    protected static final MacAddress MAC4 = getMac(4);
    protected static final MacAddress MAC5 = getMac(5);
    protected static final MacAddress MAC6 = getMac(6);
    protected static final MacAddress MAC7 = getMac(7);
    protected static final MacAddress MAC8 = getMac(8);
    protected static final MacAddress MAC9 = getMac(9);
    protected static final MacAddress MAC10 = getMac(10);
    protected static final MacAddress MAC11 = getMac(11);

    protected static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
    protected static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");

    protected static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
    protected static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
    protected static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
    protected static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
    protected static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
    protected static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
    protected static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
    protected static final HostId HID8 = HostId.hostId(MAC8, VLAN400);
    protected static final HostId HID9 = HostId.hostId(MAC9);
    protected static final HostId HID10 = HostId.hostId(MAC10);
    protected static final HostId HID11 = HostId.hostId(MAC11);

    protected static final ProviderId PID = new ProviderId("of", "foo");

    protected static final NodeId NODE_ID_1 = new NodeId("Node1");
    protected static final NodeId NODE_ID_2 = new NodeId("Node2");

    protected static final Interface V100H1 =
            new Interface("v100h1", CP1, null, null, VLAN100);
    protected static final Interface V100H2 =
            new Interface("v100h2", CP2, null, null, VLAN100);
    protected static final Interface V200H1 =
            new Interface("v200h1", CP3, null, null, VLAN200);
    protected static final Interface V200H2 =
            new Interface("v200h2", CP4, null, null, VLAN200);
    protected static final Interface V300H1 =
            new Interface("v300h1", CP5, null, null, VLAN300);
    protected static final Interface V300H2 =
            new Interface("v300h2", CP6, null, null, VLAN300);
    protected static final Interface V400H1 =
            new Interface("v400h1", CP7, null, null, VLAN400);

    protected static final Interface VNONEH1 =
            new Interface("vNoneh1", CP8, null, null, VLAN_NONE);
    protected static final Interface VNONEH2 =
            new Interface("vNoneh2", CP9, null, null, VLAN_NONE);
    protected static final Interface VNONEH3 =
            new Interface("vNoneh3", CP10, null, null, VLAN_NONE);

    protected static final Host V100HOST1 =
            new DefaultHost(PID, HID1, MAC1, VLAN100,
                            getLocation(1), Collections.singleton(IP1));
    protected static final Host V100HOST2 =
            new DefaultHost(PID, HID2, MAC2, VLAN100,
                            getLocation(2), Sets.newHashSet());
    protected static final Host V200HOST1 =
            new DefaultHost(PID, HID3, MAC3, VLAN200,
                            getLocation(3), Collections.singleton(IP2));
    protected static final Host V200HOST2 =
            new DefaultHost(PID, HID4, MAC4, VLAN200,
                            getLocation(4), Sets.newHashSet());
    protected static final Host V300HOST1 =
            new DefaultHost(PID, HID5, MAC5, VLAN300,
                            getLocation(5), Sets.newHashSet());
    protected static final Host V300HOST2 =
            new DefaultHost(PID, HID6, MAC6, VLAN300,
                            getLocation(6), Sets.newHashSet());
    protected static final Host V300HOST3 =
            new DefaultHost(PID, HID7, MAC7, VLAN300,
                            getLocation(7), Sets.newHashSet());
    protected static final Host V400HOST1 =
            new DefaultHost(PID, HID8, MAC8, VLAN400,
                            getLocation(4, 2), Sets.newHashSet());

    protected static final Host VNONEHOST1 =
            new DefaultHost(PID, HID9, MAC9, VlanId.NONE,
                            getLocation(3, 2), Sets.newHashSet());
    protected static final Host VNONEHOST2 =
            new DefaultHost(PID, HID10, MAC10, VlanId.NONE,
                            getLocation(5, 1), Sets.newHashSet());
    protected static final Host VNONEHOST3 =
            new DefaultHost(PID, HID11, MAC11, VlanId.NONE,
                            getLocation(5, 2), Sets.newHashSet());

    protected static final Set<Interface> AVAILABLE_INTERFACES =
            ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1, V300H2,
                            V400H1, VNONEH1, VNONEH2, VNONEH3);

    protected static final Set<Host> AVAILABLE_HOSTS =
            ImmutableSet.of(V100HOST1, V100HOST2, V200HOST1,
                            V200HOST2, V300HOST1, V300HOST2, V300HOST3,
                            VNONEHOST1, VNONEHOST2,
                            V400HOST1, VNONEHOST3);


    /**
     * Returns the device Id of the ith device.
     *
     * @param i the device to get the Id of
     * @return the device Id
     */
    protected static DeviceId getDeviceId(int i) {
        return DeviceId.deviceId("" + i);
    }

    /**
     * Generates a mac address by given number.
     *
     * @param n the number to generate mac address
     * @return the mac address
     */
    protected static MacAddress getMac(int n) {
        return MacAddress.valueOf(String.format("00:00:00:00:00:%s", n));
    }

    /**
     * Generates a host location by given device number.
     *
     * @param i the given number
     * @return the host location
     */
    protected static HostLocation getLocation(int i) {
        return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
    }

    /**
     * Generates host location by given device number and port number.
     *
     * @param d the device number
     * @param p the port number
     * @return the host location
     */
    protected static HostLocation getLocation(int d, int p) {
        return new HostLocation(new ConnectPoint(getDeviceId(d),
                                                 PortNumber.portNumber(p)), 123L);
    }

    /**
     * Test core service; For generate test application ID.
     */
    public class TestCoreService extends CoreServiceAdapter {
        @Override
        public ApplicationId registerApplication(String name) {
            return TestApplicationId.create(name);
        }
    }

    /**
     * Test intent service.
     * Always install or withdraw success for any Intents.
     */
    public class TestIntentService extends IntentServiceAdapter {
        IntentListener listener;
        List<IntentData> intents;

        public TestIntentService() {
            intents = Lists.newArrayList();
        }

        @Override
        public void submit(Intent intent) {
            intents.add(new IntentData(intent, IntentState.INSTALLED, new WallClockTimestamp()));
            if (listener != null) {
                IntentEvent.getEvent(IntentState.INSTALLED, intent).ifPresent(listener::event);

            }
        }

        @Override
        public void withdraw(Intent intent) {
            intents.forEach(intentData -> {
                if (intentData.intent().key().equals(intent.key())) {
                    intentData.setState(IntentState.WITHDRAWN);

                    if (listener != null) {
                        IntentEvent.getEvent(IntentState.WITHDRAWN, intent).ifPresent(listener::event);
                    }
                }
            });
        }

        @Override
        public Iterable<Intent> getIntents() {
            return intents.stream()
                    .map(IntentData::intent)
                    .collect(Collectors.toList());
        }

        @Override
        public long getIntentCount() {
            return intents.size();
        }

        @Override
        public void addListener(IntentListener listener) {
            this.listener = listener;
        }

        @Override
        public void removeListener(IntentListener listener) {
            this.listener = null;
        }
    }

    /**
     * Test leadership service.
     */
    public class TestLeadershipService extends LeadershipServiceAdapter {
        LeadershipEventListener listener;

        @Override
        public void addListener(LeadershipEventListener listener) {
            this.listener = listener;
        }

        @Override
        public void removeListener(LeadershipEventListener listener) {
            this.listener = null;
        }

        /**
         * Sends the leadership event to the listener.
         *
         * @param event the Intent event
         */
        public void sendEvent(LeadershipEvent event) {
            if (listener != null && listener.isRelevant(event)) {
                listener.event(event);
            }
        }

        @Override
        public NodeId getLeader(String path) {
            return NODE_ID_1;
        }
    }

    /**
     * Test interface service; contains all interfaces which already generated.
     */
    public class TestInterfaceService implements InterfaceService {

        @Override
        public void addListener(InterfaceListener listener) {
        }

        @Override
        public void removeListener(InterfaceListener listener) {
        }

        @Override
        public Set<Interface> getInterfaces() {
            return AVAILABLE_INTERFACES;
        }

        @Override
        public Interface getInterfaceByName(ConnectPoint connectPoint,
                                            String name) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.name().equals(name))
                    .findFirst()
                    .orElse(null);
        }

        @Override
        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.connectPoint().equals(port))
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<Interface> getInterfacesByIp(IpAddress ip) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.ipAddressesList().contains(ip))
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<Interface> getInterfacesByVlan(VlanId vlan) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.vlan().equals(vlan))
                    .collect(Collectors.toSet());
        }

        @Override
        public Interface getMatchingInterface(IpAddress ip) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.ipAddressesList().contains(ip))
                    .findFirst()
                    .orElse(null);
        }

        @Override
        public Set<Interface> getMatchingInterfaces(IpAddress ip) {
            return AVAILABLE_INTERFACES.stream()
                    .filter(intf -> intf.ipAddressesList().contains(ip))
                    .collect(Collectors.toSet());
        }
    }

    /**
     * Test VPLS store.
     */
    public class TestVplsStore extends VplsStoreAdapter {
        /**
         * Clears the store.
         */
        public void clear() {
            vplsDataMap.clear();
        }

        /**
         * Gets the store delegate.
         *
         * @return the store delegate
         */
        public StoreDelegate<VplsStoreEvent> delegate() {
            return this.delegate;
        }
    }

    /**
     * Test VPLS.
     * Provides basic VPLS functionality and stores VPLS information.
     */
    public class TestVpls implements Vpls {
        public Map<String, VplsData> testData;

        public TestVpls() {
            testData = Maps.newHashMap();
        }

        public void initSampleData() {
            testData.clear();
            VplsData vplsData = VplsData.of(VPLS1);
            vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
            vplsData.state(VplsData.VplsState.ADDED);
            testData.put(VPLS1, vplsData);

            vplsData = VplsData.of(VPLS2);
            vplsData.addInterfaces(ImmutableSet.of(V200H1, V200H2));
            vplsData.state(VplsData.VplsState.ADDED);
            testData.put(VPLS2, vplsData);
        }

        @Override
        public VplsData createVpls(String vplsName, EncapsulationType encapsulationType) {
            VplsData vplsData = VplsData.of(vplsName, encapsulationType);
            vplsData.state(VplsData.VplsState.ADDED);
            testData.put(vplsName, vplsData);
            return vplsData;
        }

        @Override
        public VplsData removeVpls(VplsData vplsData) {
            if (!testData.containsKey(vplsData.name())) {
                return null;
            }

            testData.remove(vplsData.name());
            return vplsData;
        }

        @Override
        public void addInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
            vplsData.addInterfaces(interfaces);
            testData.put(vplsData.name(), vplsData);
        }

        @Override
        public void addInterface(VplsData vplsData, Interface iface) {
            vplsData.addInterface(iface);
            testData.put(vplsData.name(), vplsData);
        }

        @Override
        public void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType) {
            vplsData.encapsulationType(encapsulationType);
            testData.put(vplsData.name(), vplsData);
        }

        @Override
        public VplsData getVpls(String vplsName) {
            return testData.get(vplsName);
        }

        @Override
        public Collection<VplsData> getAllVpls() {
            return testData.values();
        }

        @Override
        public Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
            vplsData.removeInterfaces(interfaces);
            testData.put(vplsData.name(), vplsData);
            return interfaces;
        }

        @Override
        public Interface removeInterface(VplsData vplsData, Interface iface) {
            vplsData.removeInterface(iface);
            testData.put(vplsData.name(), vplsData);
            return iface;
        }

        @Override
        public void removeAllVpls() {
            testData.clear();
        }
    }

    /**
     * Test host service; contains all hosts which already generated.
     *
     */
    public class TestHostService extends HostServiceAdapter {

        private HostListener listener;

        @Override
        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
            return AVAILABLE_HOSTS.stream()
                    .filter(host -> host.location().equals(connectPoint))
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<Host> getHostsByMac(MacAddress mac) {
            return AVAILABLE_HOSTS.stream()
                    .filter(host -> host.mac().equals(mac))
                    .collect(Collectors.toSet());
        }

        @Override
        public Iterable<Host> getHosts() {
            return AVAILABLE_HOSTS;
        }

        @Override
        public Set<Host> getHostsByVlan(VlanId vlanId) {
            return AVAILABLE_HOSTS.stream()
                    .filter(host -> host.vlan().equals(vlanId))
                    .collect(Collectors.toSet());
        }

        @Override
        public int getHostCount() {
            return AVAILABLE_HOSTS.size();
        }

        @Override
        public Host getHost(HostId hostId) {
            return AVAILABLE_HOSTS.stream()
                    .filter(host -> host.id().equals(hostId))
                    .findFirst()
                    .orElse(null);
        }

        @Override
        public void addListener(HostListener listener) {
            this.listener = listener;
        }

        public void postHostEvent(HostEvent hostEvent) {
            this.listener.event(hostEvent);
        }
    }

    /**
     * Test network configuration service.
     */
    public class TestConfigService extends NetworkConfigServiceAdapter {
        public static final String EMPTY_JSON_TREE = "{}";
        NetworkConfigListener listener;
        VplsAppConfig vplsAppConfig;

        @Override
        public void addListener(NetworkConfigListener listener) {
            this.listener = listener;
        }

        @Override
        public void removeListener(NetworkConfigListener listener) {
            this.listener = null;
        }

        /**
         * Sends network config event to listener.
         *
         * @param event the network config event
         */
        public void sendEvent(NetworkConfigEvent event) {
            if (listener != null) {
                listener.event(event);
            }
        }

        /**
         * Constructs test config service.
         * Generates an VPLS configuration with sample VPLS configs.
         */
        public TestConfigService() {
            vplsAppConfig = new VplsAppConfig();
            final ObjectMapper mapper = new ObjectMapper();
            final ConfigApplyDelegate delegate = new VplsAppConfigTest.MockCfgDelegate();
            JsonNode tree = null;
            try {
                tree = new ObjectMapper().readTree(EMPTY_JSON_TREE);
            } catch (IOException e) {
                e.printStackTrace();
            }
            vplsAppConfig.init(APPID, APP_NAME, tree, mapper, delegate);
            VplsConfig vplsConfig = new VplsConfig(VPLS1,
                                                   ImmutableSet.of(V100H1.name(), V100H2.name()),
                                                   EncapsulationType.NONE);
            vplsAppConfig.addVpls(vplsConfig);
            vplsConfig = new VplsConfig(VPLS2,
                                        ImmutableSet.of(V200H1.name(), V200H2.name()),
                                        EncapsulationType.VLAN);
            vplsAppConfig.addVpls(vplsConfig);

        }

        /**
         * Overrides VPLS config to the config service.
         *
         * @param vplsAppConfig the new VPLS config
         */
        public void setConfig(VplsAppConfig vplsAppConfig) {
            this.vplsAppConfig = vplsAppConfig;
        }

        @Override
        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
            return (C) vplsAppConfig;
        }

        @Override
        public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
            return (C) vplsAppConfig;
        }
    }

}
