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;

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

/* 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.
 */
class ArpCache {
	private final static Logger log = LoggerFactory.getLogger(ArpCache.class);
	
	private final static long ARP_ENTRY_TIMEOUT = 60000; //ms (1 min)
	
	//Protected by locking on the ArpCache object
	private final Map<InetAddress, ArpCacheEntry> arpCache;
	
	private static class ArpCacheEntry {
		private final MACAddress macAddress;
		private long timeLastSeen;	

		public ArpCacheEntry(MACAddress macAddress) {
			this.macAddress = macAddress;
			this.timeLastSeen = System.currentTimeMillis();
		}

		public MACAddress getMacAddress() {
			return macAddress;
		}
		
		public void setTimeLastSeen(long time){
			timeLastSeen = time;
		}
		
		public boolean isExpired() {
			return System.currentTimeMillis() - timeLastSeen > ARP_ENTRY_TIMEOUT;
		}
	}

	ArpCache() {
		arpCache = new HashMap<InetAddress, ArpCacheEntry>();
	}

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

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