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

import com.google.common.base.MoreObjects;
import org.onlab.packet.TpPort;
import org.onosproject.net.DeviceId;

import java.util.Comparator;
import java.util.Objects;

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

/**
 * Representation of a compute infrastructure node for CORD VTN service.
 */
public final class CordVtnNode {

    private final String hostname;
    private final NetworkAddress hostMgmtIp;
    private final NetworkAddress localMgmtIp;
    private final NetworkAddress dpIp;
    private final TpPort ovsdbPort;
    private final SshAccessInfo sshInfo;
    private final DeviceId bridgeId;
    private final String dpIntf;
    private final CordVtnNodeState state;

    public static final Comparator<CordVtnNode> CORDVTN_NODE_COMPARATOR =
            (node1, node2) -> node1.hostname().compareTo(node2.hostname());

    /**
     * Creates a new node.
     *
     * @param hostname hostname
     * @param hostMgmtIp host management network address
     * @param localMgmtIp local management network address
     * @param dpIp data plane network address
     * @param ovsdbPort port number for OVSDB connection
     * @param sshInfo SSH access information
     * @param bridgeId integration bridge identifier
     * @param dpIntf data plane interface name
     * @param state cordvtn node state
     */
    public CordVtnNode(String hostname, NetworkAddress hostMgmtIp, NetworkAddress localMgmtIp,
                       NetworkAddress dpIp, TpPort ovsdbPort, SshAccessInfo sshInfo,
                       DeviceId bridgeId, String dpIntf, CordVtnNodeState state) {
        this.hostname = checkNotNull(hostname, "hostname cannot be null");
        this.hostMgmtIp = checkNotNull(hostMgmtIp, "hostMgmtIp cannot be null");
        this.localMgmtIp = checkNotNull(localMgmtIp, "localMgmtIp cannot be null");
        this.dpIp = checkNotNull(dpIp, "dpIp cannot be null");
        this.ovsdbPort = checkNotNull(ovsdbPort, "ovsdbPort cannot be null");
        this.sshInfo = checkNotNull(sshInfo, "sshInfo cannot be null");
        this.bridgeId = checkNotNull(bridgeId, "bridgeId cannot be null");
        this.dpIntf = checkNotNull(dpIntf, "dpIntf cannot be null");
        this.state = state;
    }

    /**
     * Returns cordvtn node with new state.
     *
     * @param node cordvtn node
     * @param state cordvtn node init state
     * @return cordvtn node
     */
    public static CordVtnNode getUpdatedNode(CordVtnNode node, CordVtnNodeState state) {
        return new CordVtnNode(node.hostname,
                               node.hostMgmtIp, node.localMgmtIp, node.dpIp,
                               node.ovsdbPort,
                               node.sshInfo,
                               node.bridgeId,
                               node.dpIntf, state);
    }

    /**
     * Returns the hostname.
     *
     * @return hostname
     */
    public String hostname() {
        return this.hostname;
    }

    /**
     * Returns the host management network address.
     *
     * @return network address
     */
    public NetworkAddress hostMgmtIp() {
        return this.hostMgmtIp;
    }

    /**
     * Returns the local management network address.
     *
     * @return network address
     */
    public NetworkAddress localMgmtIp() {
        return this.localMgmtIp;
    }

    /**
     * Returns the data plane network address.
     *
     * @return network address
     */
    public NetworkAddress dpIp() {
        return this.dpIp;
    }

    /**
     * Returns the port number used for OVSDB connection.
     *
     * @return port number
     */
    public TpPort ovsdbPort() {
        return this.ovsdbPort;
    }

    /**
     * Returns the SSH access information.
     *
     * @return ssh access information
     */
    public SshAccessInfo sshInfo() {
        return this.sshInfo;
    }

    /**
     * Returns the identifier of the integration bridge.
     *
     * @return device id
     */
    public DeviceId intBrId() {
        return this.bridgeId;
    }

    /**
     * Returns the identifier of the OVSDB device.
     *
     * @return device id
     */
    public DeviceId ovsdbId() {
        return DeviceId.deviceId("ovsdb:" + this.hostMgmtIp.ip().toString());
    }

    /**
     * Returns data plane interface name.
     *
     * @return data plane interface name
     */
    public String dpIntf() {
        return this.dpIntf;
    }

    /**
     * Returns the state of the node.
     *
     * @return state
     */
    public CordVtnNodeState state() {
        return this.state;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof CordVtnNode) {
            CordVtnNode that = (CordVtnNode) obj;
            if (Objects.equals(hostname, that.hostname) &&
                    Objects.equals(hostMgmtIp, that.hostMgmtIp) &&
                    Objects.equals(localMgmtIp, that.localMgmtIp) &&
                    Objects.equals(dpIp, that.dpIp) &&
                    Objects.equals(ovsdbPort, that.ovsdbPort) &&
                    Objects.equals(sshInfo, that.sshInfo) &&
                    Objects.equals(bridgeId, that.bridgeId) &&
                    Objects.equals(dpIntf, that.dpIntf)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(hostname, hostMgmtIp, localMgmtIp, dpIp,
                            ovsdbPort, sshInfo, bridgeId, dpIntf);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("hostname", hostname)
                .add("hostMgmtIp", hostMgmtIp)
                .add("localMgmtIp", localMgmtIp)
                .add("dpIp", dpIp)
                .add("port", ovsdbPort)
                .add("sshInfo", sshInfo)
                .add("bridgeId", bridgeId)
                .add("dpIntf", dpIntf)
                .add("state", state)
                .toString();
    }
}
