package net.onrc.onos.ofcontroller.proxyarp;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.floodlightcontroller.util.MACAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * TODO clean out old ARP entries out of the cache periodically. We currently
 * don't do this which means the cache memory size will never decrease. We
 * already have a periodic thread that can be used to do this in
 * ProxyArpManager.
 */

/**
 * Implements a basic ARP cache which maps IPv4 addresses to MAC addresses.
 * Mappings time out after a short period of time (currently 1 min). We don't
 * try and refresh the mapping before the entry times out because as a
 * controller we don't know if the mapping is still needed.
 */
class ArpCache {
    private static final Logger log = LoggerFactory.getLogger(ArpCache.class);

    private static final long ARP_ENTRY_TIMEOUT = 60000; // ms (1 min)

    // Protected by locking on the ArpCache object (this)
    private final Map<InetAddress, ArpCacheEntry> arpCache;

    /**
     * Represents a MAC address entry with a timestamp in the ARP cache.
     * ARP cache entries are considered invalid if their timestamp is older
     * than a timeout value.
     */
    private static class ArpCacheEntry {
        private final MACAddress macAddress;
        private long timeLastSeen;

        /**
         * Class constructor, specifying the MAC address for the entry.
         * @param macAddress MAC address for the entry
         */
        public ArpCacheEntry(MACAddress macAddress) {
            this.macAddress = macAddress;
            this.timeLastSeen = System.currentTimeMillis();
        }

        /**
         * Returns the MAC address this entry represents.
         * @return this entry's MAC address
         */
        public MACAddress getMacAddress() {
            return macAddress;
        }

        /**
         * Update the timestamp for this entry.
         * @param time the new timestamp to update the entry with
         */
        public void setTimeLastSeen(long time) {
            timeLastSeen = time;
        }

        /**
         * Returns whether the entry has timed out or not.
         * @return true if the entry has timed out.
         */
        public boolean isExpired() {
            return System.currentTimeMillis() - timeLastSeen > ARP_ENTRY_TIMEOUT;
        }
    }

    /**
     * Class constructor.
     */
    ArpCache() {
        arpCache = new HashMap<InetAddress, ArpCacheEntry>();
    }

    /**
     * Get the MAC address that is mapped to an IP address in the ARP cache.
     * @param ipAddress the IP address to look up
     * @return the MAC address if found in the cache, null if not
     */
    synchronized MACAddress lookup(InetAddress ipAddress) {
        ArpCacheEntry arpEntry = arpCache.get(ipAddress);

        if (arpEntry == null) {
            return null;
        }

        if (arpEntry.isExpired()) {
            // Entry has timed out so we'll remove it and return null
            log.trace("Removing expired ARP entry for {}",
                    ipAddress.getHostAddress());

            arpCache.remove(ipAddress);
            return null;
        }

        return arpEntry.getMacAddress();
    }

    /**
     * Update an entry in the ARP cache. If the IP to MAC mapping is already
     * in the cache, its timestamp will be updated. If not, the entry will
     * be added with a new timestamp of the current time.
     * @param ipAddress the IP address that will be mapped in the cache
     * @param macAddress the MAC address that maps to {@code ipAddress}
     */
    synchronized void update(InetAddress ipAddress, MACAddress macAddress) {
        ArpCacheEntry arpEntry = arpCache.get(ipAddress);

        if (arpEntry != null && arpEntry.getMacAddress().equals(macAddress)) {
            arpEntry.setTimeLastSeen(System.currentTimeMillis());
        } else {
            arpCache.put(ipAddress, new ArpCacheEntry(macAddress));
        }
    }

    /**
     * Retrieve a list of all mappings in the ARP cache.
     * @return list of all ARP mappings, formatted as a human-readable string
     *
     */
    synchronized List<String> getMappings() {
        List<String> result = new ArrayList<String>(arpCache.size());

        for (Map.Entry<InetAddress, ArpCacheEntry> entry : arpCache.entrySet()) {
            result.add(entry.getKey().getHostAddress()
                    + " => "
                    + entry.getValue().getMacAddress().toString()
                    + (entry.getValue().isExpired() ? " : EXPIRED" : " : VALID"));
        }

        return result;
    }
}
