/*
 * Copyright 2015 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.provider.nil;

import com.google.common.collect.Lists;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.Link;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceAdminService;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.host.DefaultHostDescription;
import org.onosproject.net.host.HostDescription;
import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.link.LinkService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static org.onlab.util.Tools.toHex;
import static org.onosproject.net.HostId.hostId;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.device.DeviceEvent.Type.*;
import static org.onosproject.provider.nil.NullProviders.SCHEME;

/**
 * Abstraction of a provider capable to simulate some network topology.
 */
public abstract class TopologySimulator {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    protected String[] topoShape;
    protected int deviceCount;
    protected int hostCount;

    protected ServiceDirectory directory;
    protected NodeId localNode;

    protected ClusterService clusterService;
    protected MastershipService mastershipService;

    protected DeviceAdminService deviceService;
    protected HostService hostService;
    protected LinkService linkService;

    protected DeviceProviderService deviceProviderService;
    protected HostProviderService hostProviderService;
    protected LinkProviderService linkProviderService;

    protected int maxWaitSeconds = 1;
    protected int infrastructurePorts = 2;
    protected CountDownLatch deviceLatch;

    protected final List<DeviceId> deviceIds = Lists.newArrayList();

    private DeviceListener deviceEventCounter = new DeviceEventCounter();

    /**
     * Initializes a new topology simulator with access to the specified service
     * directory and various provider services.
     *
     * @param topoShape             topology shape specifier
     * @param deviceCount           number of devices in the topology
     * @param hostCount             number of hosts per device
     * @param directory             service directory
     * @param deviceProviderService device provider service
     * @param hostProviderService   host provider service
     * @param linkProviderService   link provider service
     */
    protected void init(String topoShape, int deviceCount, int hostCount,
                        ServiceDirectory directory,
                        DeviceProviderService deviceProviderService,
                        HostProviderService hostProviderService,
                        LinkProviderService linkProviderService) {
        this.deviceCount = deviceCount;
        this.hostCount = hostCount;
        this.directory = directory;

        this.clusterService = directory.get(ClusterService.class);
        this.mastershipService = directory.get(MastershipService.class);

        this.deviceService = directory.get(DeviceAdminService.class);
        this.hostService = directory.get(HostService.class);
        this.linkService = directory.get(LinkService.class);
        this.deviceProviderService = deviceProviderService;
        this.hostProviderService = hostProviderService;
        this.linkProviderService = linkProviderService;

        localNode = clusterService.getLocalNode().id();

        processTopoShape(topoShape);
    }

    /**
     * Processes the topology shape specifier.
     *
     * @param shape topology shape specifier
     */
    protected void processTopoShape(String shape) {
        this.topoShape = shape.split(",");
    }

    /**
     * Sets up network topology simulation.
     */
    public void setUpTopology() {
        prepareForDeviceEvents(deviceCount);
        createDevices();
        waitForDeviceEvents();

        createLinks();
        createHosts();
    }

    /**
     * Creates simulated devices.
     */
    protected void createDevices() {
        for (int i = 0; i < deviceCount; i++) {
            createDevice(i + 1);
        }
    }

    /**
     * Creates simulated links.
     */
    protected abstract void createLinks();

    /**
     * Creates simulated hosts.
     */
    protected abstract void createHosts();

    /**
     * Creates simulated device.
     *
     * @param i index of the device id in the list.
     */
    protected void createDevice(int i) {
        DeviceId id = DeviceId.deviceId(SCHEME + ":" + toHex(i));
        DeviceDescription desc =
                new DefaultDeviceDescription(id.uri(), Device.Type.SWITCH,
                                             "ON.Lab", "0.1", "0.1", "1234",
                                             new ChassisId(i));
        deviceProviderService.deviceConnected(id, desc);
        deviceProviderService.updatePorts(id, buildPorts(hostCount + infrastructurePorts));
        deviceIds.add(id);
    }

    /**
     * Creates simulated link between two devices.
     *
     * @param i index of one simulated device
     * @param j index of another simulated device
     */
    protected void createLink(int i, int j) {
        ConnectPoint one = new ConnectPoint(deviceIds.get(i), PortNumber.portNumber(1));
        ConnectPoint two = new ConnectPoint(deviceIds.get(j), PortNumber.portNumber(2));
        linkProviderService.linkDetected(new DefaultLinkDescription(one, two, DIRECT));
        linkProviderService.linkDetected(new DefaultLinkDescription(two, one, DIRECT));
    }

    /**
     * Creates simularted hosts for the specified device.
     *
     * @param deviceId   device identifier
     * @param portOffset port offset where to start attaching hosts
     */
    protected void createHosts(DeviceId deviceId, int portOffset) {
        String s = deviceId.toString();
        byte dByte = Byte.parseByte(s.substring(s.length() - 1), 16);
        // TODO: this limits the simulation to 256 devices & 256 hosts/device.
        byte[] macBytes = new byte[]{0, 0, 0, 0, dByte, 0};
        byte[] ipBytes = new byte[]{(byte) 192, (byte) 168, dByte, 0};

        for (int i = 0; i < hostCount; i++) {
            int port = portOffset + i + 1;
            macBytes[5] = (byte) (i + 1);
            ipBytes[3] = (byte) (i + 1);
            HostId id = hostId(MacAddress.valueOf(macBytes), VlanId.NONE);
            IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, ipBytes);
            hostProviderService.hostDetected(id, description(id, ip, deviceId, port));
        }
    }

    /**
     * Prepares to count device added/available/removed events.
     *
     * @param count number of events to count
     */
    protected void prepareForDeviceEvents(int count) {
        deviceLatch = new CountDownLatch(count);
        deviceService.addListener(deviceEventCounter);
    }

    /**
     * Waits for all expected device added/available/removed events.
     */
    protected void waitForDeviceEvents() {
        try {
            deviceLatch.await(maxWaitSeconds, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.warn("Device events did not arrive in time");
        }
        deviceService.removeListener(deviceEventCounter);
    }


    /**
     * Tears down network topology simulation.
     */
    public void tearDownTopology() {
        removeHosts();
        removeLinks();
        removeDevices();
    }

    /**
     * Removes any hosts previously advertised by this provider.
     */
    protected void removeHosts() {
        hostService.getHosts()
                .forEach(host -> hostProviderService.hostVanished(host.id()));
    }

    /**
     * Removes any links previously advertised by this provider.
     */
    protected void removeLinks() {
        linkService.getLinks()
                .forEach(link -> linkProviderService.linkVanished(description(link)));
    }

    /**
     * Removes any devices previously advertised by this provider.
     */
    protected void removeDevices() {
        prepareForDeviceEvents(deviceService.getDeviceCount());
        deviceService.getDevices()
                .forEach(device -> deviceService.removeDevice(device.id()));
        waitForDeviceEvents();
    }


    /**
     * Produces a device description from the given device.
     *
     * @param device device to copy
     * @return device description
     */
    static DeviceDescription description(Device device) {
        return new DefaultDeviceDescription(device.id().uri(), device.type(),
                                            device.manufacturer(),
                                            device.hwVersion(), device.swVersion(),
                                            device.serialNumber(), device.chassisId());
    }

    /**
     * Produces a link description from the given link.
     *
     * @param link link to copy
     * @return link description
     */
    static DefaultLinkDescription description(Link link) {
        return new DefaultLinkDescription(link.src(), link.dst(), link.type());
    }

    /**
     * Produces a host description from the given host.
     *
     * @param host host to copy
     * @return host description
     */
    static DefaultHostDescription description(Host host) {
        return new DefaultHostDescription(host.mac(), host.vlan(), host.location(),
                                          host.ipAddresses());
    }

    /**
     * Generates a host description from the given id and location information.
     *
     * @param hostId   host identifier
     * @param ip       host IP
     * @param deviceId edge device
     * @param port     edge port
     * @return host description
     */
    static HostDescription description(HostId hostId, IpAddress ip,
                                       DeviceId deviceId, int port) {
        HostLocation location = new HostLocation(deviceId, portNumber(port), 0L);
        return new DefaultHostDescription(hostId.mac(), hostId.vlanId(), location, ip);
    }

    /**
     * Generates a list of a configured number of ports.
     *
     * @param portCount number of ports
     * @return list of ports
     */
    protected List<PortDescription> buildPorts(int portCount) {
        List<PortDescription> ports = Lists.newArrayList();
        for (int i = 0; i < portCount; i++) {
            ports.add(new DefaultPortDescription(PortNumber.portNumber(i), true,
                                                 Port.Type.COPPER, 0));
        }
        return ports;
    }

    // Counts down number of device added/available/removed events.
    private class DeviceEventCounter implements DeviceListener {
        @Override
        public void event(DeviceEvent event) {
            DeviceEvent.Type type = event.type();
            if (type == DEVICE_ADDED || type == DEVICE_REMOVED ||
                    type == DEVICE_AVAILABILITY_CHANGED) {
                deviceLatch.countDown();
            }
        }
    }
}