/*
 * Copyright 2016-present 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.drivers.juniper;

import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.behaviour.LinkDiscovery;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.drivers.juniper.JuniperUtils.LinkAbstraction;
import static org.onosproject.drivers.juniper.JuniperUtils.parseJuniperLldp;
import static org.onosproject.drivers.juniper.JuniperUtils.requestBuilder;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.drivers.juniper.JuniperUtils.REQ_LLDP_NBR_INFO;
import static org.slf4j.LoggerFactory.getLogger;


/**
 * Retrieve Links discovered by the device LLDP.
 * Tested with MX240 junos 14.2
 */
@Beta
public class LinkDiscoveryJuniperImpl extends AbstractHandlerBehaviour
        implements LinkDiscovery {

    private final Logger log = getLogger(getClass());

    @Override
    public Set<LinkDescription> getLinks() {
        DeviceId localDeviceId = this.handler().data().deviceId();
        NetconfController controller =
                checkNotNull(handler().get(NetconfController.class));
        NetconfSession session =
                controller.getDevicesMap().get(localDeviceId).getSession();

        String reply;
        try {
            reply = session.get(requestBuilder(REQ_LLDP_NBR_INFO));
        } catch (IOException e) {
            log.warn("Failed to retrieve ports for device {}", localDeviceId);
            return ImmutableSet.of();
        }
        log.debug("Reply from device {} : {}", localDeviceId, reply);
        Set<LinkAbstraction> linkAbstractions = parseJuniperLldp(
                XmlConfigParser.loadXml(new ByteArrayInputStream(reply.getBytes())));
        log.debug("Set of LinkAbstraction discovered {}", linkAbstractions);

        DeviceService deviceService = this.handler().get(DeviceService.class);
        Set<LinkDescription> descriptions = new HashSet<>();

        //for each lldp neighbor create two LinkDescription
        for (LinkAbstraction linkAbs : linkAbstractions) {

            //find source port by local port name
            Optional<Port> localPort = deviceService.getPorts(localDeviceId).stream()
                    .filter(port -> {
                        if (linkAbs.localPortName.equals(
                                port.annotations().value(PORT_NAME))) {
                            return true;
                        }
                        return false;
                    }).findAny();
            if (!localPort.isPresent()) {
                log.warn("Port name {} does not exist in device {}",
                         linkAbs.localPortName, localDeviceId);
                continue;
            }
            //find destination device by remote chassis id
            com.google.common.base.Optional<Device> dev = Iterables.tryFind(
                    deviceService.getAvailableDevices(),
                    input -> input.chassisId().equals(linkAbs.remoteChassisId));

            if (!dev.isPresent()) {
                log.warn("Device with chassis ID {} does not exist",
                         linkAbs.remoteChassisId);
                continue;
            }
            Device remoteDevice = dev.get();

            //find destination port by interface index
            Optional<Port> remotePort = deviceService.getPorts(remoteDevice.id())
                    .stream().filter(port -> {
                if (port.annotations().value("index") != null &&
                        Integer.parseInt(port.annotations().value("index"))
                                == linkAbs.remotePortIndex) {
                    return true;
                }
                return false;
            }).findAny();
            if (!remotePort.isPresent()) {
                log.warn("Port with index {} does not exist in device {}",
                         linkAbs.remotePortIndex, remoteDevice.id());
                continue;
            }

            JuniperUtils.createBiDirLinkDescription(localDeviceId,
                                                    localPort.get(),
                                               remoteDevice.id(),
                                               remotePort.get(),
                                               descriptions);

        }
        return descriptions;
    }
}
