package org.onlab.onos.sdnip;

import java.util.List;

import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.sdnip.config.BgpPeer;
import org.onlab.onos.sdnip.config.BgpSpeaker;
import org.onlab.onos.sdnip.config.Interface;
import org.onlab.onos.sdnip.config.InterfaceAddress;
import org.onlab.onos.sdnip.config.SdnIpConfigService;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Manages the connectivity requirements between peers.
 */
public class PeerConnectivity {

    private static final Logger log = LoggerFactory.getLogger(
            PeerConnectivity.class);

    // TODO these shouldn't be defined here
    private static final short BGP_PORT = 179;
    private static final int IPV4_BIT_LENGTH = 32;

    private final SdnIpConfigService configInfoService;
    private final InterfaceService interfaceService;
    private final IntentService intentService;

    // TODO this sucks.
    private int intentId = 0;

    public PeerConnectivity(SdnIpConfigService configInfoService,
            InterfaceService interfaceService, IntentService intentService) {
        this.configInfoService = configInfoService;
        this.interfaceService = interfaceService;
        this.intentService = intentService;
    }

    public void start() {
        // TODO are any of these errors?
        if (interfaceService.getInterfaces().isEmpty()) {

            log.warn("The interface in configuration file is empty. "
                    + "Thus, the SDN-IP application can not be started.");
        } else if (configInfoService.getBgpPeers().isEmpty()) {

            log.warn("The BGP peer in configuration file is empty."
                    + "Thus, the SDN-IP application can not be started.");
        } else if (configInfoService.getBgpSpeakers() == null) {

            log.error("The BGP speaker in configuration file is empty. "
                    + "Thus, the SDN-IP application can not be started.");
            return;
        }

        setupBgpPaths();
        setupIcmpPaths();
    }

    /**
     * Sets up paths for all {@link BgpSpeaker}s and all external peers.
     * <p/>
     * Run a loop for all BGP speakers and a loop for all BGP peers outside.
     * Push intents for paths from each BGP speaker to all peers. Push intents
     * for paths from all peers to each BGP speaker.
     */
    private void setupBgpPaths() {
        for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
                .values()) {
            log.debug("Start to set up BGP paths for BGP speaker: {}",
                    bgpSpeaker);
            ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();

            List<InterfaceAddress> interfaceAddresses =
                    bgpSpeaker.interfaceAddresses();

            for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {

                log.debug("Start to set up BGP paths between BGP speaker: {} "
                        + "to BGP peer: {}", bgpSpeaker, bgpPeer);

                Interface peerInterface = interfaceService.getInterface(
                        bgpPeer.connectPoint());
                if (peerInterface == null) {
                    log.error("Can not find the corresponding Interface from "
                            + "configuration for BGP peer {}",
                            bgpPeer.ipAddress());
                    continue;
                }

                IpAddress bgpdAddress = null;
                for (InterfaceAddress interfaceAddress : interfaceAddresses) {
                    if (interfaceAddress.connectPoint().equals(
                            peerInterface.connectPoint())) {
                        bgpdAddress = interfaceAddress.ipAddress();
                        break;
                    }
                }
                if (bgpdAddress == null) {
                    log.debug("There is no interface IP address for bgpPeer: {}"
                            + " on interface {}", bgpPeer, bgpPeer.connectPoint());
                    return;
                }

                IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
                ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();

                // install intent for BGP path from BGPd to BGP peer matching
                // destination TCP port 179

                // TODO: The usage of PacketMatchBuilder will be improved, then we
                // only need to new the PacketMatchBuilder once.
                // By then, the code here will be improved accordingly.
                 TrafficSelector selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_TCP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchTcpDst(BGP_PORT)
                        .build();

                TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                        .build();

                PointToPointIntent intentMatchDstTcpPort = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdConnectPoint, bgpdPeerConnectPoint);
                intentService.submit(intentMatchDstTcpPort);
                log.debug("Submitted BGP path intent matching dst TCP port 179 "
                        + "from BGPd {} to peer {}: {}",
                        bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);

                // install intent for BGP path from BGPd to BGP peer matching
                // source TCP port 179
                selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_TCP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchTcpSrc(BGP_PORT)
                        .build();

                PointToPointIntent intentMatchSrcTcpPort = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdConnectPoint, bgpdPeerConnectPoint);
                intentService.submit(intentMatchSrcTcpPort);
                log.debug("Submitted BGP path intent matching src TCP port 179"
                        + "from BGPd {} to peer {}: {}",
                        bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);

                // install intent for reversed BGP path from BGP peer to BGPd
                // matching destination TCP port 179
                selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_TCP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchTcpDst(BGP_PORT)
                        .build();

                PointToPointIntent reversedIntentMatchDstTcpPort = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdPeerConnectPoint, bgpdConnectPoint);
                intentService.submit(reversedIntentMatchDstTcpPort);
                log.debug("Submitted BGP path intent matching dst TCP port 179"
                        + "from BGP peer {} to BGPd {} : {}",
                        bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);

                // install intent for reversed BGP path from BGP peer to BGPd
                // matching source TCP port 179
                selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_TCP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchTcpSrc(BGP_PORT)
                        .build();

                PointToPointIntent reversedIntentMatchSrcTcpPort = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdPeerConnectPoint, bgpdConnectPoint);
                intentService.submit(reversedIntentMatchSrcTcpPort);
                log.debug("Submitted BGP path intent matching src TCP port 179"
                        + "from BGP peer {} to BGPd {} : {}",
                        bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);

            }
        }
    }

    /**
     * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
     * located in other external networks.
     * <p/>
     * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
     * intents for paths from each BGP speaker to all peers. Push intents
     * for paths from all peers to each BGP speaker.
     */
    private void setupIcmpPaths() {
        for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
                .values()) {
            log.debug("Start to set up ICMP paths for BGP speaker: {}",
                    bgpSpeaker);
            ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
            List<InterfaceAddress> interfaceAddresses = bgpSpeaker
                    .interfaceAddresses();

            for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {

                Interface peerInterface = interfaceService.getInterface(
                        bgpPeer.connectPoint());

                if (peerInterface == null) {
                    log.error("Can not find the corresponding Interface from "
                            + "configuration for BGP peer {}",
                            bgpPeer.ipAddress());
                    continue;
                }
                IpAddress bgpdAddress = null;
                for (InterfaceAddress interfaceAddress : interfaceAddresses) {
                    if (interfaceAddress.connectPoint().equals(
                            peerInterface.connectPoint())) {
                        bgpdAddress = interfaceAddress.ipAddress();
                        break;
                    }

                }
                if (bgpdAddress == null) {
                    log.debug("There is no IP address for bgpPeer: {} on "
                            + "interface port: {}", bgpPeer,
                            bgpPeer.connectPoint());
                    return;
                }

                IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
                ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();

                // install intent for ICMP path from BGPd to BGP peer
                TrafficSelector selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_ICMP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .build();

                TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                        .build();

                PointToPointIntent intent = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdConnectPoint, bgpdPeerConnectPoint);
                intentService.submit(intent);
                log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
                        + " {}", bgpdAddress, bgpdPeerAddress, intent);

                // install intent for reversed ICMP path from BGP peer to BGPd
                selector = DefaultTrafficSelector.builder()
                        .matchEthType(Ethernet.TYPE_IPV4)
                        .matchIPProtocol(IPv4.PROTOCOL_ICMP)
                        .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
                        .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
                        .build();

                PointToPointIntent reversedIntent = new PointToPointIntent(
                        nextIntentId(), selector, treatment,
                        bgpdPeerConnectPoint, bgpdConnectPoint);
                intentService.submit(reversedIntent);
                log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
                        + " {} : {}",
                        bgpdPeerAddress, bgpdAddress, reversedIntent);
            }
        }
    }

    private IntentId nextIntentId() {
        return new IntentId(intentId++);
    }
}
