<?xml version = "1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml">
<meta charset="UTF-8">

<head>
	<title>NDN Get File via WebSocket</title>
	
	<script type="text/javascript" src="../build/ndn-js.js"></script>

	<script type="text/javascript">
		hostip = "localhost";
		var ndncon = new NDN({port:9696,host:hostip});
		//var ndncon = new NDN({port:9696,host:hostip,verify:false});
        
///////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
		 * Closure for calling expressInterest to fetch big file.
		 */                                                
		var ContentClosure = function ContentClosure(ndn, T0) {
		    // Inherit from Closure.
		    Closure.call(this);
		    
		    this.T0 = T0;  // start time
		    this.ndn = ndn;
			this.totalBlocks = 0;  // total # of segments delivered to usr; 
			                       // TODO: in this test script we simply discard the content after it is received
			                       //  should consider some way to buffer the whole data in future refactor  --- SWT
		    
		    // We should always start with the first element so the first content object cannot be ooo data
		    //this.firstReceivedSegmentNumber = null;
		    //this.firstReceivedContentObject = null;
		    
		    // statistic counters
		    this.ooo_count = 0;  // out-of-order content object counter; 
		                         // when this counter reaches 3, apply fast retransmission alg.
		    this.pkt_recved = 0;  // total # of content object received
		    this.timed_out = 0;   // totle # of timed out interest
		    this.interest_sent = 1;  // there is an initial interest before calling the closure upcall
		    this.dups = 0;  // total # of dup content segments
		    
		    this.max_window = 32;  // max window size
		    this.max_retrans = 5;  // max # of trial before give up; if we fail on one segment, the entire process is aborted
		    
		    this.snd_una = 0;  // pointer to unacked segments
		    this.snd_wnd = 1;  // current window size
		    this.snd_nxt = 1;  // pointer to next interest to be sent
		    
		    this.ooo_table_size = 128;
		    this.ooo_table = [];  // hash table to mark ooo segments
		    
		    this.terminated = false;  // Set this flag after we receive all the segments; 
		};
		
		ContentClosure.prototype.upcall = function(kind, upcallInfo) {
			this.pkt_recved++;
			
		    if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
		    	if (this.terminated == false) {
			    	this.timed_out++;
			    	
			    	// Reduce window size to 1
			    	this.snd_wnd = 1;
			    	
			    	// Retransmit interest for this segment
			    	this.ndn.expressInterest(upcallInfo.interest.name, this);
					//console.log("Resend interest sent for " + upcallInfo.interest.name.getName());
					document.getElementById('content').innerHTML += "<p>Resend interest sent for " 
					                         + upcallInfo.interest.name.getName() + "</p>";
					this.interest_sent++;
					
			    	document.getElementById('content').innerHTML += "<p>Interest " + upcallInfo.interest.name.getName() + " time out.</p>";
			        document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>";
			        document.getElementById('content').innerHTML += "<p>Total number of packets: " + this.pkt_recved + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of dup segments: " + this.dups + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of interest sent: " + this.interest_sent + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of time-out interest: " + this.timed_out + "</p>";
					
					document.getElementById('content').innerHTML += "<p>SND_UNA: " + this.snd_una + "</p>";
					document.getElementById('content').innerHTML += "<p>SND_WND: " + this.snd_wnd + "</p>";
					document.getElementById('content').innerHTML += "<p>SND_NXT: " + this.snd_nxt + "</p>";
				}
		        return Closure.RESULT_OK;
		    }
		    
		    if (kind == Closure.UPCALL_CONTENT_BAD) {
		    	console.log("NdnProtocol.ContentClosure: signature verification failed");
		    	console.log(upcallInfo.contentObject.name.getName());
		    	console.log(DataUtils.toHex(upcallInfo.contentObject.signature.Witness).toLowerCase());
		    	return Closure.RESULT_OK;
		    }
		    
		    if (!(kind == Closure.UPCALL_CONTENT ||
		          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
		        // The upcall is not for us.
		        return Closure.RESULT_ERR;
		    
		    var contentObject = upcallInfo.contentObject;
		    if (contentObject.content == null) {
		        console.log("NdnProtocol.ContentClosure: contentObject.content is null");
		        return Closure.RESULT_ERR;
		    }
		
		    // Use the segmentNumber to load multiple segments.
		    var segmentNumber = DataUtils.bigEndianToUnsignedInt
		    						(contentObject.name.components[contentObject.name.components.length - 1]);
		    //console.log("Seg # " + segmentNumber + " received");
		    //console.log("Seg name " + contentObject.name.getName());
		    
		    /*
	        if (this.firstReceivedSegmentNumber == null) {
	            // This is the first call.
	            this.firstReceivedSegmentNumber = segmentNumber;
	            if (segmentNumber != 0) {
	                // Special case: Save this content object for later and request segment zero.
	                // SWT: this should not happen in normal case; 
	                //      ccnd should always return the first segment if no seg# is specified
	                this.firstReceivedContentObject = contentObject;
	                var componentsForZero = contentObject.name.components.slice
	                    (0, contentObject.name.components.length - 1);
	                componentsForZero.push([0]);
	                this.ndn.expressInterest(new Name(componentsForZero), this);
	                return Closure.RESULT_OK;
	            }
	        }
	        */
			
			// Process received data here...
			// Count content length
			//nameStr = escape(contentObject.name.getName());
			//document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
			//document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>";
		    
		    /*
		    // Check for the special case if the saved content is for the next segment that we need.
		    if (this.firstReceivedContentObject != null && 
		        this.firstReceivedSegmentNumber == segmentNumber + 1) {
		        // Substitute the saved contentObject send its content and keep going.
		        contentObject = this.firstReceivedContentObject;
		        segmentNumber = segmentNumber + 1;
		        // Clear firstReceivedContentObject to save memory.
		        this.firstReceivedContentObject = null;
		        
		        // Process received data here...
		    	// Count content length
		    	//nameStr = escape(contentObject.name.getName());
				//document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
				//document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>";
				this.totalBlocks++;
		    }
		    */
			
			// Record final seg# if present
			var finalSegmentNumber = null;
			if (contentObject.signedInfo != null && contentObject.signedInfo.finalBlockID != null)
				finalSegmentNumber = DataUtils.bigEndianToUnsignedInt(contentObject.signedInfo.finalBlockID);
			
			// Check for out-of-order segment
			if (segmentNumber != this.snd_una) {
				//console.log("Out-of-order segment #" + segmentNumber + " received.");
				document.getElementById('content').innerHTML += "<p>Out-of-order segment #" + segmentNumber + " received.</p>";
				this.ooo_count++;
				
				if (segmentNumber >= this.snd_nxt || segmentNumber < this.snd_una) {
					// Discard segment that is out of window
					//console.log("Out-of-window segment #" + segmentNumber);
					document.getElementById('content').innerHTML += "<p>Out-of-window segment #" + segmentNumber + "</p>";
					return Closure.RESULT_OK;
				}
				// Mark this segment in hash table
				var slot = segmentNumber % this.ooo_table_size;
				this.ooo_table[slot] = segmentNumber;
				
				if (this.ooo_count == 3) {
					// Fast retransmit
					// TODO: expressInterest for seg# = this.snd_una
					//this.snd_wnd = Math.floor(this.snd_wnd / 2) + 3;
				} else if (this.ooo_count > 3) {
					//this.snd_wnd++;
					// TODO: send a new interest if allowed by snd_wnd
					// SWT: what if we never receive the first unacked segment???
				}
				
				return Closure.RESULT_OK;
			}
			
			// In-order segment; slide window forward
			this.snd_una++
			this.totalBlocks++;
			var slot = this.snd_una % this.ooo_table_size;
			while (this.ooo_table[slot] != undefined) {
				// continue to move forward until we reach a hole in the seg# sequence
				this.ooo_table[slot] = undefined;
				this.snd_una++;
				this.totalBlocks++;
				slot = this.snd_una % this.ooo_table_size;
			}
			
			if (finalSegmentNumber != null && this.snd_una == finalSegmentNumber + 1) {
				// All blocks before final block, including final block, is received. Mission complete.
				// Record stop time and print statistic result
				this.terminated = true;
				var T1 = new Date();
				document.getElementById('content').innerHTML += "<p>Final block received.</p>";
				document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>";
				document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of packets: " + this.pkt_recved + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of dup segments: " + this.dups + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of interest sent: " + this.interest_sent + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of time-out interest: " + this.timed_out + "</p>";
				
				document.getElementById('content').innerHTML += "<p>SND_UNA: " + this.snd_una + "</p>";
				document.getElementById('content').innerHTML += "<p>SND_WND: " + this.snd_wnd + "</p>";
				document.getElementById('content').innerHTML += "<p>SND_NXT: " + this.snd_nxt + "</p>";
				return Closure.RESULT_OK;
			}
			
			// Adjust window size
			if (this.snd_wnd < this.max_window) {
				this.snd_wnd++;
				//console.log("Window size after adjust: " + this.snd_wnd);
			}
			
			// Send the next interest if allowed by snd_wnd
			var nextNameComponents = contentObject.name.components.slice(0, contentObject.name.components.length - 1);
			//console.log("SND_UNA: " + this.snd_una);
			//console.log("SND_NXT: " + this.snd_nxt);
			while (this.snd_nxt - this.snd_una < this.snd_wnd) {
				// Make a name for the next segment and get it.
				var segmentNumberPlus1 = DataUtils.nonNegativeIntToBigEndian(this.snd_nxt);
				// Put a 0 byte in front.
				var nextSegmentNumber = new Uint8Array(segmentNumberPlus1.length + 1);
				nextSegmentNumber.set(segmentNumberPlus1, 1);
				
				nextNameComponents.push(nextSegmentNumber);
				
				var nextName = new Name(nextNameComponents);
				this.ndn.expressInterest(nextName, this);
				//console.log("Interest sent for seg # " + this.snd_nxt + " name " + nextName.getName());
				this.interest_sent++;
				
				this.snd_nxt++;
				nextNameComponents.pop();  // Remove segment number from components
			}
			
			return Closure.RESULT_OK;
		};
		
		/*
		 * Convert the big endian Uint8Array to an unsigned int.
		 * Don't check for overflow.
		 */
		function ArrayToNum(bytes) {
		    var result = 0;
		    for (var i = 0; i < bytes.length; ++i) {
		        result = result * 10;
		        result += (bytes[i] - 48);
		    }
		    return result;
		}
		
		/*
		 * Convert the int value to a new big endian Uint8Array and return.
		 * If value is 0 or negative, return Uint8Array(0). 
		 */
		function NumToArray(value) {
		    value = Math.round(value);
		    if (value <= 0)
		        return new Uint8Array(0);
		    
		    numString = value.toString();
		    var size = numString.length;
		    var result = new Uint8Array(size);
		    for (i = 0; i < size; i++) {
		    	result[i] = numString.charCodeAt(i);
		    }
		    return result;
		}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        /*
        var AsyncGetClosure = function AsyncGetClosure(T0) {
        	this.T0 = T0;  // Start time
        	// Inherit from Closure.
			Closure.call(this);
		};
		
		AsyncGetClosure.prototype.upcall = function(kind, upcallInfo) {
			//console.log("Closure.upcall() executed.");
			if (kind == Closure.UPCALL_FINAL) {
				// Do nothing.
			} else if (kind == Closure.UPCALL_CONTENT) {
				var T1 = new Date();
				
				var content = upcallInfo.contentObject;
				nameStr = escape(content.name.getName());
				document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>"; 
				document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
				document.getElementById('content').innerHTML += "<p>Content buffer length: " + content.content.length + "</p>";
				//console.log("In callback, nameStr: " + nameStr);
				//console.log("In callback, content: ");
				//console.log(content.content.length);
				//document.getElementById('content').innerHTML += contentObjectToHtml(content);
			} else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
				console.log("Closure.upcall called with interest time out.");
			}
			return Closure.RESULT_OK;
		};
		*/
		
		function run() {
			document.getElementById('content').innerHTML += "<p>Started...</p>";
			//ndn.expressInterest(new Name(document.getElementById('interest').value), new AsyncGetClosure( new Date() ));
			var name = new Name(document.getElementById('interest').value);
            ndncon.expressInterest( name, 
                    new ContentClosure( ndncon, new Date() ));
		}
		
	</script>
	
</head>
<body >

	<form>
		Please Enter an Interest:<br />
		<input id="interest" type="text" name="INTEREST" size="50" value="/wentao.shang/mars.jpg/%00" /> 
	</form>

	<button onclick="run()">Fetch Content</button>
	
	<p id="content">Result: <br/></p>

</body>
</html>
