/*
 * Copyright 2014 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.onlab.onos.sdnip.config;

import java.util.List;
import java.util.Objects;

import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import org.onlab.packet.MacAddress;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;

/**
 * Represents a BGP daemon in SDN network.
 * <p>
 * Each BGP speaker has a attachment point, which includes a switch DPID and a
 * switch port. Each BGP speaker has one MAC address and several IP addresses,
 * which are used to peer with BGP peers outside the SDN network. For each
 * peer outside the SDN network, we configure a different IP address to BGP
 * speaker inside the SDN network.
 * </p>
 * <p>
 * Each BGP speaker has a name, which is a unique identifying String that is
 * used to reference this speaker in the configuration.
 * </p>
 */
public class BgpSpeaker {
    private final String name;
    private final ConnectPoint connectPoint;
    private final MacAddress macAddress;
    private List<InterfaceAddress> interfaceAddresses;

    /**
     * Class constructor used by the JSON library to create an object.
     *
     * @param name the name of the BGP speaker inside SDN network
     * @param attachmentDpid the DPID where the BGP speaker is attached to
     * @param attachmentPort the port where the BGP speaker is attached to
     * @param macAddress the MAC address of the BGP speaker
     */
    @JsonCreator
    public BgpSpeaker(@JsonProperty("name") String name,
            @JsonProperty("attachmentDpid") String attachmentDpid,
            @JsonProperty("attachmentPort") int attachmentPort,
            @JsonProperty("macAddress") String macAddress) {

        this.name = name;
        this.macAddress = MacAddress.valueOf(macAddress);
        this.connectPoint = new ConnectPoint(
                DeviceId.deviceId(SdnIpConfigurationReader.dpidToUri(attachmentDpid)),
                PortNumber.portNumber(attachmentPort));
    }

    /**
     * Sets the addresses we configured for the BGP speaker on all virtual
     * {@link Interface}s.
     *
     * @param interfaceAddresses a list of IP addresses of the BGP speaker
     * configured on all virtual interfaces
     */
    @JsonProperty("interfaceAddresses")
    public void setInterfaceAddresses(
            List<InterfaceAddress> interfaceAddresses) {
        this.interfaceAddresses = interfaceAddresses;
    }

    /**
     * Gets the BGP speaker name.
     *
     * @return the BGP speaker name
     */
    public String name() {
        return name;
    }

    /**
     * Gets the connect point where the BGP speaker is attached.
     *
     * @return the connect point
     */
    public ConnectPoint connectPoint() {
        return connectPoint;
    }

    /**
     * Gets the MAC address of the BGP speaker.
     *
     * @return the MAC address
     */
    public MacAddress macAddress() {
        return macAddress;
    }

    /**
     * Gets all IP addresses configured on all {@link Interface}s of the
     * BGP speaker.
     *
     * @return a list of IP addresses of the BGP speaker configured on all
     * virtual interfaces
     */
    public List<InterfaceAddress> interfaceAddresses() {
        return interfaceAddresses;
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof BgpSpeaker)) {
            return false;
        }

        BgpSpeaker otherBgpSpeaker = (BgpSpeaker) other;

        return  name.equals(otherBgpSpeaker.name) &&
                connectPoint.equals(
                        otherBgpSpeaker.connectPoint) &&
                macAddress.equals(otherBgpSpeaker.macAddress) &&
                interfaceAddresses.equals(otherBgpSpeaker.interfaceAddresses);
    }

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

    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("speakerName", name)
                .add("connectPoint", connectPoint)
                .add("macAddress", macAddress)
                .add("interfaceAddresses", interfaceAddresses)
                .toString();
    }
}
