#######################################
# EXERCISE SETUP                      #
#######################################

# Basename for the generated files
set filenameBase "S02E02P01"

#######################################
# SIMULATOR STARTUP                   #
#######################################

# Create simulator
set ns [new Simulator]

#######################################
# COLOR SETUP                         #
#######################################

$ns color 0 Blue
#$ns color 1 Red
#$ns color 2 Yellow
#$ns color 3 Green
#$ns color 4 Purple
#$ns color 5 Pink

#######################################
# FILES                               #
#######################################

# Trace file
set tf [open $filenameBase.out.tr w]
$ns trace-all $tf

# Nam tracefile
set nf [open $filenameBase.out.nam w]
$ns namtrace-all $nf

# Big FTP windowfile
set bwf [open $filenameBase.FTP.wf w]

# Big FTP slow start threshold
set btf [open $filenameBase.SST.wf w]

# Filesize file
set fs [open $filenameBase.FS.tr w]

#######################################
# NODE SETUP                          #
#######################################

# Create nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]

# Creating links
$ns duplex-link $n0 $n1 10Mb 10ms DropTail
$ns duplex-link $n0 $n2 10Mb 10ms DropTail
$ns duplex-link $n0 $n4 10Mb 10ms DropTail
$ns duplex-link $n3 $n1 10Mb 10ms DropTail
$ns duplex-link $n5 $n1 10Mb 10ms DropTail
#$ns duplex-link $n0 $n1 10Mb 10ms RED
#$ns duplex-link $n0 $n1 10Mb 10ms SFQ

#Queue limiting
$ns queue-limit $n0 $n1 20
$ns queue-limit $n0 $n4 2000

#######################################
# NAM SETUP                           #
#######################################

#Give node position (for NAM)
$ns duplex-link-op $n2 $n0 orient right-down
$ns duplex-link-op $n4 $n0 orient right-up
$ns duplex-link-op $n0 $n1 orient right
$ns duplex-link-op $n3 $n1 orient left-down
$ns duplex-link-op $n5 $n1 orient left-up
$ns duplex-link-op $n0 $n1 queuePos 0.5

######################################
# BIG FTP CONNECTION                 #
######################################

set bigTcp [new Agent/TCP]
$ns attach-agent $n2 $bigTcp
set bigSink [new Agent/TCPSink]
$ns attach-agent $n3 $bigSink
$ns connect $bigTcp $bigSink
$bigTcp set fid_ 0 
$bigTcp set window_ 80
set bigFtp [new Application/FTP]
$bigFtp attach-agent $bigTcp
$ns at 0.1 "$bigFtp start"
$ns at 0.1 "plotValues $bigTcp $bwf $btf"
$ns at 24.9 "$bigFtp stop"

######################################
# FTP CONNECTION GENERATE            #
######################################

# Random generator
set fileRng [new RNG]
$fileRng seed 0
set timeRng [new RNG]
$timeRng seed 0

# Random filesize generator
set RVSize [new RandomVariable/Pareto]
$RVSize set avg_ 15000
$RVSize set shape_ 1.5
$RVSize use-rng $fileRng

# Random sending time generator
set RVTime [new RandomVariable/Exponential]
$RVTime set avg_ 0.05
$RVTime use-rng $timeRng

# Generating TCP FTP Connections
for {set j 1} {$j <= 3} {incr j} {
	set fileTime [expr $j*5]
	for {set i 1} {$i <= 40} {incr i} {
		
		set ftpNum [expr $i*$j]
	        # Starting TCP Agent
	        set tcp($ftpNum) [new Agent/TCP]
	        #set tcp($i) [new Agent/TCP/Newreno]
	        #set tcp($i) [new Agent/TCP/Vegas]
	        $ns attach-agent $n4 $tcp($ftpNum)

	        # Starting Sink agent
	        set sink($ftpNum) [new Agent/TCPSink]
	        $ns attach-agent $n5 $sink($ftpNum)

	        # Connecting TCP agent to Sink agent
	        $ns connect $tcp($ftpNum) $sink($ftpNum)

	        # Setting connection parameters
	        $tcp($ftpNum) set fid_ $ftpNum 
		$tcp($ftpNum) set window_ 80

	        # Starting FTP connection
	        set ftp($ftpNum) [new Application/FTP]
	        $ftp($ftpNum) attach-agent $tcp($ftpNum)
		
		# Saving filesize
		set fileSize [expr [$RVSize value]]
		set fileTime [expr $fileTime+[$RVTime value]]
		puts $fs "$fileTime $fileSize"
	        # Timing
		$ns at $fileTime  "$ftp($ftpNum) send $fileSize"
	}
}

#######################################
# TIMING                              #
#######################################

# End of simulation
$ns at 25.0 "finish"

#######################################
# FUNCTIONS                           #
#######################################

# Procedure for plotting window size
proc plotValues {wfS wf tf} {
	global ns
	set time 0.1
	set now [$ns now]
	set cwnd [$wfS set cwnd_]
	set ssthresh [$wfS set ssthresh_]
	puts $wf "$now $cwnd"
	puts $tf "$now $ssthresh"
	$ns at [expr $now+$time] "plotValues $wfS $wf $tf"
}

# Finish function
proc finish {} {
	#finalize trace files
	global ns nf tf filenameBase
	$ns flush-trace
	close $tf
	close $nf
	
	exec nam $filenameBase.out.nam &
	exit 0
}

#######################################
# RUNNING SIMULATOR                   #
#######################################

# Running the network simulator
$ns run

