/*
 * 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.routing.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.Config;

import java.util.Objects;
import java.util.Optional;
import java.util.Set;

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

/**
 * Configuration object for BGP config.
 */
public class BgpConfig extends Config<ApplicationId> {

    public static final String SPEAKERS = "bgpSpeakers";
    public static final String CONNECT_POINT = "connectPoint";
    public static final String NAME = "name";
    public static final String PEERS = "peers";

    /**
     * Gets the set of configured BGP speakers.
     *
     * @return BGP speakers
     */
    public Set<BgpSpeakerConfig> bgpSpeakers() {
        Set<BgpSpeakerConfig> speakers = Sets.newHashSet();

        JsonNode speakersNode = object.get(SPEAKERS);

        if (speakersNode == null) {
            return speakers;
        }

        speakersNode.forEach(jsonNode -> {
            Set<IpAddress> listenAddresses = Sets.newHashSet();
            jsonNode.path(PEERS).forEach(addressNode ->
                            listenAddresses.add(IpAddress.valueOf(addressNode.asText()))
            );

            Optional<String> name;
            if (jsonNode.get(NAME) == null) {
                name = Optional.empty();
            } else {
                name = Optional.of(jsonNode.get(NAME).asText());
            }

            speakers.add(new BgpSpeakerConfig(name,
                    ConnectPoint.deviceConnectPoint(jsonNode.path(CONNECT_POINT).asText()),
                    listenAddresses));
        });

        return speakers;
    }

    /**
     * Examines whether a name of BGP speaker exists in configuration.
     *
     * @param name name of BGP speaker being search
     * @return speaker
     */
    public BgpSpeakerConfig getSpeakerWithName(String name) {
        for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
            if (speaker.name().filter(name::equals).isPresent()) {
                return speaker;
            }
        }
        return null;
    }

    /**
     * Adds BGP speaker to configuration.
     *
     * @param speaker BGP speaker configuration entry
     */
    public void addSpeaker(BgpSpeakerConfig speaker) {
        ObjectNode speakerNode = JsonNodeFactory.instance.objectNode();

        speakerNode.put(NAME, speaker.name().get());

        speakerNode.put(CONNECT_POINT, speaker.connectPoint().elementId().toString()
                + "/" + speaker.connectPoint().port().toString());

        ArrayNode peersNode = speakerNode.putArray(PEERS);
        for (IpAddress peerAddress: speaker.peers()) {
            peersNode.add(peerAddress.toString());
        }

        ArrayNode speakersArray = bgpSpeakers().isEmpty() ?
                initBgpConfiguration() : (ArrayNode) object.get(SPEAKERS);
        speakersArray.add(speakerNode);
    }

    /**
     * Removes BGP speaker from configuration.
     *
     * @param speakerName BGP speaker name
     */
    public void removeSpeaker(String speakerName) {
        ArrayNode speakersArray = (ArrayNode) object.get(SPEAKERS);

        for (int i = 0; i < speakersArray.size(); i++) {
            if (speakersArray.get(i).hasNonNull(NAME) &&
                    speakersArray.get(i).get(NAME).asText().equals(speakerName)) {
                speakersArray.remove(i);
                return;
            }
        }
    }

    /**
     * Adds peering address to BGP speaker.
     *
     * @param speakerName name of BGP speaker
     * @param peerAddress peering address to be added
     */
    public void addPeerToSpeaker(String speakerName, IpAddress peerAddress) {
        JsonNode speakersNode = object.get(SPEAKERS);
        speakersNode.forEach(jsonNode -> {
            if (jsonNode.hasNonNull(NAME) &&
                    jsonNode.get(NAME).asText().equals(speakerName)) {
                ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
                for (int i = 0; i < peersNode.size(); i++) {
                    if (peersNode.get(i).asText().equals(peerAddress.toString())) {
                        return; // Peer already exists.
                    }
                }
                peersNode.add(peerAddress.toString());
            }
        });
    }

    /**
     * Finds BGP speaker peering with a given external peer.
     *
     * @param peerAddress peering address to be removed
     * @return speaker
     */
    public BgpSpeakerConfig getSpeakerFromPeer(IpAddress peerAddress) {
        for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
            if (speaker.peers().contains(peerAddress)) {
                return speaker;
            }
        }
        return null;
    }

    /**
     * Removes peering address from BGP speaker.
     *
     * @param speaker BGP speaker configuration entries
     * @param peerAddress peering address to be removed
     */
    public void removePeerFromSpeaker(BgpSpeakerConfig speaker, IpAddress peerAddress) {
        JsonNode speakersNode = object.get(SPEAKERS);
        speakersNode.forEach(jsonNode -> {
            if (jsonNode.hasNonNull(NAME) &&
                    jsonNode.get(NAME).asText().equals(speaker.name().get())) {
                ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
                for (int i = 0; i < peersNode.size(); i++) {
                    if (peersNode.get(i).asText().equals(peerAddress.toString())) {
                        peersNode.remove(i);
                        return;
                    }
                }
            }
        });
    }

    /**
     * Creates empty configuration for BGP speakers.
     *
     * @return empty array of BGP speakers
     */
    private ArrayNode initBgpConfiguration() {
        return object.putArray(SPEAKERS);
    }


    /**
     * Configuration for a BGP speaker.
     */
    public static class BgpSpeakerConfig {

        private Optional<String> name;
        private ConnectPoint connectPoint;
        private Set<IpAddress> peers;

        public BgpSpeakerConfig(Optional<String> name, ConnectPoint connectPoint,
                                Set<IpAddress> peers) {
            this.name = checkNotNull(name);
            this.connectPoint = checkNotNull(connectPoint);
            this.peers = checkNotNull(peers);
        }

        public Optional<String> name() {
            return name;
        }

        public ConnectPoint connectPoint() {
            return connectPoint;
        }

        public Set<IpAddress> peers() {
            return peers;
        }

        /**
         * Examines if BGP peer is connected.
         *
         * @param peer IP address of peer
         * @return result of search
         */
        public boolean isConnectedToPeer(IpAddress peer) {
            for (final IpAddress entry : peers()) {
                if (entry.equals(peer)) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof BgpSpeakerConfig) {
                final BgpSpeakerConfig that = (BgpSpeakerConfig) obj;
                return Objects.equals(this.name, that.name) &&
                        Objects.equals(this.connectPoint, that.connectPoint) &&
                        Objects.equals(this.peers, that.peers);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return Objects.hash(name, connectPoint, peers);
        }
    }
}
