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

import com.google.common.base.MoreObjects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.pim.PIMHelloOption;

import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

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

/**
 * Represents a PIM neighbor.
 */
public class PIMNeighbor {

    // IP Address of this neighbor
    private final IpAddress ipAddr;

    // MAC Address of the neighbor (Need for sending J/P)
    private final MacAddress macAddr;

    // Hello Options
    // Our hello opt holdTime
    private final short holdTime;

    // Our hello opt prune delay
    private final int pruneDelay;

    // Neighbor priority
    private final int priority;

    // Our current genId
    private final int genId;

    private final long upTime;

    // Our timestamp for this neighbor
    private long lastRefresh;

    /**
     * Class constructor.
     *
     * @param ipAddress neighbor IP address
     * @param macAddress neighbor MAC address
     * @param holdTime hold time
     * @param pruneDelay prune delay
     * @param priority priority
     * @param genId generation ID
     */
    public PIMNeighbor(IpAddress ipAddress, MacAddress macAddress,
                       short holdTime, int pruneDelay, int priority, int genId) {
        this.ipAddr = checkNotNull(ipAddress);
        this.macAddr = checkNotNull(macAddress);
        this.holdTime = holdTime;
        this.pruneDelay = pruneDelay;
        this.priority = priority;
        this.genId = genId;

        this.upTime = System.currentTimeMillis();
    }

    /**
     * Gets the IP address of our neighbor.
     *
     * @return the IP address of our neighbor
     */
    public IpAddress ipAddress() {
        return ipAddr;
    }

    /**
     * Gets the MAC address of this neighbor.
     *
     * @return the mac address
     */
    public MacAddress macAddress() {
        return macAddr;
    }

    /**
     * Gets our neighbor's hold time.
     *
     * @return the hold time
     */
    public short holdtime() {
        return holdTime;
    }

    /**
     * Gets our neighbor's prune delay.
     *
     * @return our neighbor's prune delay
     */
    public int pruneDelay() {
        return pruneDelay;
    }

    /**
     * Gets our neighbor's priority.
     *
     * @return our neighbor's priority
     */
    public int priority() {
        return priority;
    }

    /**
     * Gets our neighbor's generation ID.
     *
     * @return our neighbor's generation ID
     */
    public int generationId() {
        return genId;
    }

    /**
     * Gets the last time we heard a HELLO from this neighbor.
     *
     * @return last refresh time
     */
    public long lastRefresh() {
        return lastRefresh;
    }

    /**
     * Gets the time that we first learnt of this neighbor.
     *
     * @return up time
     */
    public long upTime() {
        return upTime;
    }

    /**
     * Refreshes this neighbor's last seen timestamp.
     */
    public void refreshTimestamp() {
        lastRefresh = System.currentTimeMillis();
    }

    /**
     * Returns whether this neighbor is expired or not.
     *
     * @return true if the neighbor is expired, otherwise false
     */
    public boolean isExpired() {
        return lastRefresh + TimeUnit.SECONDS.toMillis(holdTime)
                < System.currentTimeMillis();
    }

    /**
     * Creates a PIM neighbor based on an IP, MAC, and collection of PIM HELLO
     * options.
     *
     * @param ipAddress neighbor IP address
     * @param macAddress neighbor MAC address
     * @param opts options from the PIM HELLO packet
     * @return new PIM neighbor
     */
    public static PIMNeighbor createPimNeighbor(IpAddress ipAddress,
                                                MacAddress macAddress,
                                                Collection<PIMHelloOption> opts) {

        int generationID = PIMHelloOption.DEFAULT_GENID;
        short holdTime = PIMHelloOption.DEFAULT_HOLDTIME;
        int priority = PIMHelloOption.DEFAULT_PRIORITY;
        int pruneDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;

        for (PIMHelloOption opt : opts) {
            short type = opt.getOptType();
            ByteBuffer value = ByteBuffer.wrap(opt.getValue());

            if (type == PIMHelloOption.OPT_GENID) {
                generationID = value.getInt();
            } else if (type == PIMHelloOption.OPT_HOLDTIME) {
                holdTime = value.getShort();
            } else if (type == PIMHelloOption.OPT_PRIORITY) {
                priority = value.getInt();
            } else if (type == PIMHelloOption.OPT_PRUNEDELAY) {
                pruneDelay = value.getInt();
            } else if (type == PIMHelloOption.OPT_ADDRLIST) {
                // TODO: Will implement someday
            }
        }

        return new PIMNeighbor(ipAddress, macAddress, holdTime, pruneDelay, priority, generationID);
    }

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

        PIMNeighbor that = (PIMNeighbor) other;

        return this.ipAddr.equals(that.ipAddress()) &&
                this.macAddr.equals(that.macAddress()) &&
                this.genId == that.genId &&
                this.holdTime == that.holdTime &&
                this.priority == that.priority;
    }

    @Override
    public int hashCode() {
        return Objects.hash(ipAddr, macAddr, genId, holdTime, priority);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("ipAddress", ipAddr)
                .add("macAddress", macAddr)
                .add("generationId", genId)
                .add("holdTime", holdTime)
                .add("priority", priority)
                .add("pruneDelay", pruneDelay)
                .toString();
    }

}
