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

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();
    }
}
