<?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="../tools/build/ndn-js.js"></script>

	<script type="text/javascript">
		//hostip = "131.179.196.232";
		hostip = "localhost";
		var ndncon = new NDN({port:9696,host:hostip});
        ndncon.transport.connectWebSocket(ndncon);
        
///////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
		 * 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>";
				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/%00" /> 
	</form>

	<button onclick="run()">Fetch Content</button>
	
	<p id="content">Result: <br/></p>

</body>
</html>
