 #!/usr/bin/perl
use strict;
use warnings;
use DBI;#使用資料庫

#接收參數與前置處理
my $id=$ARGV[0];#使用者帳號
my $date=$ARGV[1];#送出模擬日期
my $range=$ARGV[2];#模擬範圍座標
my $start=$ARGV[3];#起點座標 Like:121.21,45
$start=~s/,/ /g;#用空白取代","
my $end=$ARGV[4];#終點座標
$end=~s/,/ /g;#用空白取代","
my $T_light=$ARGV[5];#紅綠燈時間
my $cnum=$ARGV[6];#車輛數
my $frequency=$ARGV[7];#模擬次數
my $simtime=$ARGV[8];#模擬時間
my $speedEV=$ARGV[9];#救護車速度(km/hr)
my $speedNV=$ARGV[10];#一般車輛速度(km/hr)
$speedNV=($speedNV*1000/3600);#單位轉換(m/s)
my $method=$ARGV[11];#選擇的行車策略
my $way=$ARGV[12];#要過濾的way tag
$way=~s/=/ or highway=/g;#修改銜接字串
my $cpu1=$ARGV[13];#用來執行SUMO
my $cpu2=$ARGV[14];#用來執行NS2
my $port=$ARGV[15];#連接SUMO及NS2的port
my $starttime=0;#起始模擬時間
my $diffDIS=500;#自動換算結點距離比對值
my $SWID;#起始街道ID
my $EWID;#終點街道ID
my $checkTimeCount;

#預設檔案目錄以及檔名
my $sumoDir="/usr/share/sumo/";#sumo目錄
my $scriptDir="/var/www/EMS_script/";#script目錄
my $movebin="/var/www/EMS_script/movebin/";#movebin目錄
my $usrDir="/var/www/EMS_script/usr";#使用者data目錄
my $map="MAP.osm.xml";#下載圖檔的osm檔名
my $net="MAP.net.xml";#輸出net檔名
my $trip="TRIP.trips.xml";#輸出的trip檔名
my $flow="FLOW.flow.xml";#輸出的flow檔名
my $route="ROUTE.rou.xml";#輸出的route檔名
my $cfg="SUMO.sumo.cfg";#輸出的cfg檔名
my $tr="SUMO.sumo.tr";#輸出的tr檔名
my $tclout="out.tcl";#輸出的tcl檔名

#SQL相關參數
my $db = "EMS"; #database 名稱
my $host = "localhost"; #host name
my $user = "EMS"; #資料庫帳號
my $password = "spring67721"; #資料庫密碼

#email相關參數(gmail)
my $fromaddr = '**********';
my $toaddrs = $id;
my $GID = '***********';
my $GPWD = '************';

#下載圖檔
sub GetMap{
	#從OSM下載圖資,有三個來源可以選
	system "wget", "-O", "$usrDir/$id/$date/temp.osm", "http://overpass-api.de/api/map?bbox=$range";
	#system "wget","-c" ,"-t" ,"40" , "-O", "$usrDir/$id/$date/temp.osm", "http://api.openstreetmap.fr/api/0.6/map?bbox=$range";
	#system "wget", "-O", "$usrDir/$id/$date/temp.osm", "http://api.openstreetmap.org/api/0.6/map?bbox=$range";
	print "MAP Download done\n";#測試顯示列

	#圖資物件過濾
	system "./osmfilter $usrDir/$id/$date/temp.osm --keep='highway=$way' --drop-version --drop-author -o=$usrDir/$id/$date/$map";
	print "Filter finish\n";#測試顯示列
	system "ls", "$usrDir/$id/$date/";

	#移除暫存圖檔
	#system "rm","$usrDir/$id/$date/temp.osm";
	#print "rm temp file\n";#測試顯示列

	#紅綠燈自動生成
	print "run auto_tls.pl\n";#測試顯示列
	system "perl", "auto_tls.pl", "$usrDir/$id/$date/$map", "$usrDir/$id/$date/$net", "$usrDir/$id/$date/$net", "$T_light";
}

#執行前置作業
sub prepare{
	#建立使用者目錄
	if (!(-d "$usrDir/$id")){
		print "Create user dir!\n";
		system "mkdir", "$usrDir/$id";
		print "Create sim dir!\n";
		system "mkdir", "$usrDir/$id/$date";
	}
	else{
		print "Create sim dir!\n";
		system "mkdir", "$usrDir/$id/$date";
	}

	$checkTimeCount =0;
	#下載圖檔並且確認是否正常轉換格式
	while (!(-e "$usrDir/$id/$date/$net")) {
		print "Download Map!\n";
		$checkTimeCount++;
		print "times: $checkTimeCount \n";
		&GetMap;
	}

	#起終點轉換街道ID
	#取得起點
	$SWID = readpipe "perl calway.pl $usrDir/$id/$date/$map $start $usrDir/$id/$date/$net $diffDIS";
	print "Start way ID:" . $SWID . "\n";
	#取得終點
	$EWID = readpipe "perl calway.pl $usrDir/$id/$date/$map $end $usrDir/$id/$date/$net $diffDIS";
	print "END way ID:" . $EWID . "\n";
}

#模擬參數設定與檔案產生
sub config{
	#設定街道限速
	print "Change average speed\n";
	system "sed -i 's/speed=\"[^a-zA-Z]*\"/speed=\"$speedNV\"/' $usrDir/$id/$date/$net";

	#建立車輛隨機移動路徑
	print "Create trip...\n";
	system "python", "$sumoDir/tools/randomTrips.py", "-n", "$usrDir/$id/$date/$net", "-e", "$simtime", "-o", "$usrDir/$id/$date/$trip", "-p" , 24;

	#建立救護車車流
	print "Create flow...\n";
	#system  "echo '<flows><flow id=\"A\" from=\"$SWID\" to=\"$EWID\" begin=\"5\" end=\"300\" number=\"1\" color=\"0,0,1\" /></flows>' > $usrDir/$id/$date/$flow";
	#vType 'rescue' 特定的救護車類別
	system  "echo '<flows><vType id=\"rescue\" vClass=\"emergency\" guiShape=\"emergency\" maxSpeed=\"19.4\" speedFactor=\"1.5\"><param key=\"has.bluelight.device\" value=\"true\"/></vType><flow id=\"A\" from=\"$SWID\" begin=\"5\" end=\"300\" number=\"1\" color=\"0,0,1\" type=\"rescue\" /></flows>' > $usrDir/$id/$date/$flow";

	#整合車輛隨機路徑以及救護車車流
	print "Create route...\n";
    #system "$sumoDir/bin/duarouter --ignore-errors -n $usrDir/$id/$date/$net -t $usrDir/$id/$date/$trip -f $usrDir/$id/$date/$flow -o $usrDir/$id/$date/$route -b $starttime -e $simtime";
    system "$sumoDir/bin/duarouter --ignore-errors -n $usrDir/$id/$date/$net --route-files $usrDir/$id/$date/$trip,$usrDir/$id/$date/$flow -o $usrDir/$id/$date/$route -b $starttime -e $simtime";

	#修正Route.xml格式
	#system"sed -i 's/id=\"A.0\"/id=\"A_0\" type=\"ev\"/' $usrDir/$id/$date/$route";
	system"sed -i 's/id=\"A.0\"/id=\"A_0\"/' $usrDir/$id/$date/$route";

	#設定救護車參數以及最高速線(km/hr)
	print "Specialize ev speed: $speedEV\n";#測試顯示列
	#system "java", "-classpath", "$movebin", "SpecializeEV", "$usrDir/$id/$date/$route", "$speedEV";

	#建立cfg檔
	print "Config...\n";
    system "java -classpath $movebin cfgEditor -b $starttime -e $simtime -n $usrDir/$id/$date/$net -r $usrDir/$id/$date/$route -o $usrDir/$id/$date/$cfg -t /$usrDir/$id/$date/$tr";

	print "Run...\n";
    system "$sumoDir/bin/sumo -c $usrDir/$id/$date/$cfg";

	print "tcl...\n";
    system "java -Xmx8000M -classpath $movebin idv/xxjyen/nsgenerator/NSGeneratorMain -n $usrDir/$id/$date/$net -tr $usrDir/$id/$date/$tr -o $usrDir/$id/$date/$tclout $port $EWID";
}

#執行模擬
sub run{
	#將method轉為陣列
	my @simMethod = split('',$method);

	#建立輸出儲存目錄
	chdir "$usrDir/$id/$date" or die "dir not exist\n";
	mkdir ("output",0777) or die "can't create output dir\n";
    mkdir ("output/Data",0777) or die "can't create data dir\n";
    mkdir ("output/Trip",0777) or die "can't create trip dir\n";
	mkdir ("output/Figure",0777) or die "can't create figure dir\n";
	my $nsoutput;#ns結果輸出檔案名稱

	#開始模擬
	for (my $var = 1; $var <= $frequency; $var++) {
		#每次模擬前都重新建立路網
		&config;
		for (my $key = 0; $key < @simMethod; $key++) {
			#顯示目前模擬次數以及使用方法
			print "Simulation times: $var\n";
			print "Method: $simMethod[$key]\n";

			#執行模擬
			if ($simMethod[$key] eq "A") {
				$nsoutput = $cnum."_A_".$var.".txt";
				print $nsoutput;
                print "\nCPU1: $cpu1\n";
                print "\nCPU2: $cpu2\n";
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_A_$var.txt &\"";
				sleep 5;
				#導航
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -un 1 -crt 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "B"){
				$nsoutput = $cnum."_B_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_B_$var.txt &\"";
				sleep 5;
				#導航 & 車子讓路
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -un 1 -uv 1 -crt 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "C"){
				$nsoutput = $cnum."_C_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_C_$var.txt &\"";
				sleep 5;
				#導航 ＆ 紅綠燈
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -un 1 -ut 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "D"){
				$nsoutput = $cnum."_D_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_D_$var.txt &\"";
				sleep 5;
				#導航 ＆ 車子讓路 ＆ 紅綠燈
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -un 1 -uv 1 -ut 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "E"){
				$nsoutput = $cnum."_E_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_E_$var.txt &\"";
				sleep 5;
				#車子讓路
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -uv 1 -crt 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "F"){
				$nsoutput = $cnum."_F_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_F_$var.txt &\"";
				sleep 5;
				#紅綠燈
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -ut 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			elsif($simMethod[$key] eq "G"){
				$nsoutput = $cnum."_G_".$var.".txt";
				print $nsoutput;
                system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_G_$var.txt &\"";
				sleep 5;
				#車子讓路 ＆ 紅綠燈
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -uv 1 -ut 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
			else{
				$nsoutput = $cnum."_X_".$var.".txt";
				print $nsoutput;
				system "taskset -c $cpu1 bash -c \"sumo -c $usrDir/$id/$date/$cfg --remote-port $port --tripinfo-output stdout |grep A_0 >output/Trip/trip_X_$var.txt &\"";
                sleep 5;
				#None
				system "taskset -c $cpu2 bash -c \"ns $usrDir/$id/$date/out.tcl -crt 1 &>output/Data/$nsoutput\"";
				sleep 5;
			}
		}
	}
}


#更新資料庫
sub update{
	#連接Database
	my $dbh = DBI->connect ("DBI:mysql:database=$db:host=$host", $user, $password)
		or die "Can't connect to database: $DBI::errstr\n";
	#準備執行SQL指令，更新結束時間以及模擬狀態
	my $sth = $dbh->prepare("UPDATE `Simulation` SET `status` = '2', `etime` = NOW() , `progress` = '100%' WHERE `ID` = '$id'  AND `date` = '$date'");

	#執行SQL指令
	$sth->execute();

	#結束command
	$sth->finish();

	#中斷資料庫連結
	$dbh->disconnect or warn "Disconnection error: $DBI::errstr\n";
}

sub plot{
	#切換至script目錄
	chdir "$scriptDir" or die "dir not exist\n";

	#計算平均地圖edge分佈&到達時間&Trip分析
    system "perl NetAnalysis.pl $usrDir/$id/$date/$net >$usrDir/$id/$date/output/Data/netdist.txt";
	system "python calresult.py $usrDir/$id/$date/output/Data $cnum $frequency $method >$usrDir/$id/$date/output/Data/result.txt";
    system "perl calTrip.pl $usrDir/$id/$date/output/Trip $frequency $method";

	#轉換輸出DATA
	system "perl format.pl $method $usrDir/$id/$date/output/Data/result.txt $usrDir/$id/$date/output/Data/ $id $date";

	#繪製圖檔
    system "gnuplot -e \"infile='$usrDir/$id/$date/output/Data/netdist.txt'; outfile='$usrDir/$id/$date/output/Figure/NetDist.png'\" NetDist.gp";
    system "gnuplot -e \"infile='$usrDir/$id/$date/output/Trip/trip.txt'; outfile='$usrDir/$id/$date/output/Figure/Trip_RG.png'\" Trip_RG.gp";
    system "gnuplot -e \"infile='$usrDir/$id/$date/output/Trip/trip.txt'; outfile='$usrDir/$id/$date/output/Figure/Trip_PC.png'\" Trip_PC.gp";
    system "gnuplot -e \"infile='$usrDir/$id/$date/output/Trip/trip.txt'; outfile='$usrDir/$id/$date/output/Figure/Trip_TLP.png'\" Trip_TLP.gp";

	my @namelist = qw(RG PC TLP);
	foreach my $name (@namelist){
		system "gnuplot -e \"infile='$usrDir/$id/$date/output/Data/$name.dat'; outfile='$usrDir/$id/$date/output/Figure/$name.png'\" plot.gp";
	}
}

sub tar{
    #將模擬結果生成壓縮檔
    system "cp $usrDir/Readme.txt $usrDir/$id/$date/output/";
    system "tar czvf $usrDir/$id/$date/output.tar.gz -C $usrDir/$id/$date output";
}

sub mail{
	#送出通知mail
	system "python mail.py $fromaddr $toaddrs $GID $GPWD";
}

&prepare;
&run;
&update;
&plot;
&tar;
&mail;
