package Test::AutomationFramework 0.01; 
use 5.012003;
use strict;
use warnings;
use Date::Manip;
use File::Path;
use Test::More;
use Getopt::Long;
use File::Copy;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
help
processTCSettings
processTC
processProperty
);

our $VERSION = '0.06';   # processTC(;;;;;;listVars;execAll) , processTC, processProp done

	my $propertyOp='';	my $regression=0; my $help=0;
	my $scriptName = $0; $scriptName =~ s/\\/\\\\/g;
	my $tcNamePattern	= "TC*";
	my $reportHtml  	= 'index.htm';
	my $reportHtml1 	= '_tcReport_.html';
	my $reportHistoryHtml 	= '_tcReportHistory_.html';
	my $SvrDrive = 'c:'; 
	my $SvrProjName = '_testProj_'; 
	my $SvrTCName = '_SvrTCName_';
	my $SvrTCNamePattern = "test*"; 
	my $SvrPropNamePattern = '.*';
	my $SvrPropValuePattern = ".*";
	my $SvrTCNameExecPattern = $SvrTCNamePattern;
	my $tcOp= 'exec';	
 	my $pr2Screen = 1;
	my $SvrLogDir = ''.$SvrProjName.'';

sub new { my $package = shift;
	return bless({}, $package);
}

sub tcLoop {
	if ($pr2Screen == 1) {print "Processing ......" ; } else { print "";}
	&tcPre(); my $returnValue = &tcMain(); &tcPost(); 
	if ($pr2Screen==1) {print "\n - Completed -\n"; } else { print "";}
	return $returnValue;
}
sub tcPre {
	##################### PrePRocessor #####################
 	&createFile($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1,"");
 	&createFile($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHistoryHtml,"");
 	&appendtoFile($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHistoryHtml,"<html><body><pre>\n");
	########################################################
}
sub tcMain {
	##################### Test Execution ###################
	my $returnValue ='';
	foreach my $eachTC (<$SvrDrive/$SvrProjName/$SvrTCNamePattern>) {				# TC Filter

		if ( &matchProperty ($SvrPropNamePattern, $SvrPropValuePattern, $eachTC) =~ /true/i) {	# Property Filter
				$eachTC = &getRoot($eachTC);
			if ($propertyOp !~ /^\s*$/) { printf "%20s\n", &processProperty($eachTC, $propertyOp); 
			}  # PropertyManagement
			elsif (($tcOp !~ /^\s*$/)&&(&getRoot($eachTC)=~/$SvrTCNameExecPattern/))  { 
				&updateWeb($eachTC,1);
				$returnValue = $returnValue. &processTC("","$tcOp=$eachTC",$pr2Screen);   	  # TC Execution
				&updateWeb($eachTC,0);
		    	}
 			&logTC($eachTC);						# TC Logging
			# &reportTC($eachTC,"","lastValue");				# TC Reporting	-> _tcReport_.html
 			&reportTCHistory($eachTC);					# TC ReporHistory -> _tcReportHistory_.html
		}
	}
	return $returnValue;
	########################################################
}
sub tcPost {
	##################### Post PRocessor ###################
 	&appendtoFile($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHistoryHtml,"</pre></body></html>\n");
	&prHtml1();
  	&appendtoFileFile($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1, $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml);
	&prHtml2();
	########################################################
} 

sub updateWeb {
 	my $tcname = 'TC_tc1'; $tcname = shift if @_;
 	my $scrollamount = 0 ; $scrollamount = shift if @_;
	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	if (-e $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml) {
		open Fin, $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml;
		open Fout, ">".$SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml."_";
		while ($_ = <Fin>) {
		if ( $_ =~ /$tcname\b/i) {
			$_ =~ /scrollamount=\s*(\d+)\s*/;
			$_ =~ s/scrollamount=\s*$1\s*/scrollamount=$scrollamount/;
			print Fout $_;} else { print Fout $_; }
		}
		close Fin;
		close Fout;
		copy ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml."_", $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml);
	}
}

################################################################################
#	Subroutine Name : logTC
#		Function: create TC _tcLog.html for each TC
#	Input Parameters: Test Case name
#	Output/Returns  : c:\inetpub\wwwroot\*.html
################################################################################
sub logTC {		# 	Update TC Log on webUI (TH:WebUI)
    my $currentTime  = &UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z" );
    my $tcname       = shift; $tcname = &getTCName ($tcname);
	 if (&getTCLogFname($tcname) =~ /_tcLog\.txt\s*$/ ) { 
	    my 	$webLogText =  &readFile("$tcname\\_tcLog.html");
	       	$webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	       	$webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	       	$webLogText =~ s/\n/_nl_/g;
	       	$webLogText =~ s/\s*_nl_\s*/\n/g;
    		my $fileText = &readFile(&getTCLogFname($tcname)); # todo Histery
	 	open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
         	print Fout "-------------------- Update on $currentTime Start-------\n";
    		print Fout  $fileText;
         	print Fout "\n-------------------- Update on $currentTime End --------\n"; 
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } elsif (&getTCLogFname ($tcname) =~ /_tcLogAppend\.txt\s*$/) { 
	    my  $webLogText =  &readFile("$tcname\\_tcLog.html");
	        $webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	        $webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	        $webLogText =~ s/\n/_nl_/g;
       		$webLogText =~ s/\s*_nl_\s*/\n/g;
    		my $fileText = &readFile(&getTCLogFname($tcname)); # todo Histery
		open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
		print Fout $webLogText;
         	print Fout "-------------------- Update on $currentTime Start-------\n";
    		print Fout  $fileText;
         	print Fout "\n-------------------- Update on $currentTime End --------\n";
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } else {
		open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
         	print Fout "-------------------- Update on $currentTime Start-------\n";
    		print Fout "$tcname has no log";
         	print Fout "\n-------------------- Update on $currentTime End --------\n";
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } 
	 return "$tcname";
}

################################################################################
#	Subroutine Name : getTCLogFname
#		Function: get valid Log (new log) fname 
#	Input Parameters: c:\TC*\_thLog.txt
#	Output/Returns  : noLog or hasWWWLog
################################################################################
sub getTCLogFname	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'\\thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'\\'.'thProperty.txt');
    }
    my $tcNameLogWeb = $tcName.'\\_tcLog.html';
    if (-e $tcNameLogWeb) {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLogWeb, $ctime, $blksize, $blocks
	    ) = stat($tcNameLogWeb);
    	if ($mtimePropertyFile - $mtimeLogWeb>= 0 ) { return $tcNameLogWeb; }
    }

    my $tcNameLog = $tcName."\\_tcLogAppend.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName\\_tcLog.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }

    return "noLog"; 

#    $tcNameLog = "c:\\Inetpub\\wwwroot\\_tcLogs_\\$tcName.html";
#    my (
#        $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
#        $size, $atime, $mtimeLog, $ctime, $blksize, $blocks
#    ) = stat($tcNameLog);
#    if ( -e $tcNameLog ) { return $tcNameLog; }
    return "noLog"; 
}

################################################################################
#	Subroutine Name : reportTCHistory
#		Function: append TC result History to htmlLog
#	Input Parameters: Test Case name
################################################################################
sub reportTCHistory {
	my $tcname = shift;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHistoryHtml, " ---------------------- TestCase: <a name=\"$tcname\"> $tcname </a>-----------------------\n");
	&appendtoFile ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHistoryHtml, $fileText);
}


################################################################################
#	Subroutine Name : reportTC
#		Function: report TC results on STDOUT and Update TCProj HTML
#	Input Parameters: TC Name
#			  TC PropertyName = tcRunResult
#			  TC Report Type: 0 = latest 1 = historyical
#	Output/Returns  : TC Reports displayed on webUI
################################################################################
sub reportTC() {		# TC Report Function (TH:TC Report)
    my $cmd=''; $cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
    my $timeSpan  = "2000!now"; 
    my $tcname          = $_[0]; my $propertyPattern = $_[1]; my $reportType = $_[2]; 
    $tcname = &getTCName($tcname);
    my ($timeSpanStart, $timeSpanEnd, $isInSpan, $returnValue, $beautifiedStr, $beautifiedStr4Web); 
    my ($propertyName, $startTime, $endTime, $comment1, $comment2) ;
    my $passCtr =0; my $failCtr = 0; my $totalTime=0; my $avgResponseTime; my $propertyValue ='';
    my $totalTimeDummy;
    if( $propertyPattern =~ /^\s*$/) {   $propertyPattern = 'tcRunResult';}
    if( $reportType =~ /^\s*$/) {   $reportType = 'lastValue';}

     if ($timeSpan) { $_ = $timeSpan;
 	    ($timeSpanStart, $timeSpanEnd ) = split( /!|\|/, $timeSpan );
 	    $timeSpanStart = &ParseDate($timeSpanStart);
 	    $timeSpanEnd   = &ParseDate($timeSpanEnd);
 	}
    open Fin, "$tcname\\thProperty.txt" || die "Can't open file:$!";
    while ( $_ = <Fin> ) { chop;
         if ( $_ =~ /$propertyPattern/i ) {
                ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
                my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) );
                my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) );
                if   ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; }
                else                                        { $isInSpan = -1; }
		my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g;
		my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
		my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S;
		if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";}
             if ( $isInSpan == 1 ) {
		 if ( $propertyPattern =~ /tcRunResult/i ) {
		      $beautifiedStr = sprintf "%15s %-15s %-25s%-s", $propertyValue, $totalSec.'s', $startTime, $comment1;
		      if ($propertyValue =~ /pass/i) {$passCtr++; $totalTime =$totalTime + $totalSec;}
		      if ($propertyValue =~ /fail/i) {$failCtr++; $totalTime =$totalTime + $totalSec;}
		 } else {
                 	$beautifiedStr = $_;
             	 }    # endif for /tcRunResult/
                 if ( $reportType =~ /history/i ) {    		# return property history
                     $returnValue .= "$beautifiedStr\n";
                 }
                 elsif ( $reportType =~ /lastValue/i ) {    	# returen last property
                     $returnValue = $beautifiedStr;
                 }
                 elsif ( $reportType =~ /forWeb/i ) {    	# for the web
                         $returnValue .= $beautifiedStr4Web;
                     }
	     } # endif for InSpan
         }    # endif for /propertyPattern/
    }
    	if ($passCtr + $failCtr == 0) { 
	$avgResponseTime = 0; } else {
	$avgResponseTime = $totalTime / ($passCtr + $failCtr); 
	}
	my $qtpHost; my $ATResultFname; my %color; my $color = 'gray'; my @color; my $colorIndex = 0; my $QASvrName; 
	if ($propertyValue =~ /pass/i) { $color = "Green"; } elsif ($propertyValue =~ /fail/i) { $color = 'Red'; }
	$color[0]=1;

	my $dirRoot = &getRoot($tcname); 
	my $TCCtrToolTip = sprintf "Click to exec TC (Avg Response Time %.2fs)", $avgResponseTime; 
	my $TCScrollAmount = 0; my $CtrSeparator = "|";
	my $tmp = sprintf( "<li style=\"color:$color;\"><span style=\"color:black;\"><a href=\"file:\\\\\\$tcname/_tcLog.html\" title=\"Click to see TC Logs\"> %-40s</a> <a href=\"file:///$SvrDrive/$SvrProjName/${reportHistoryHtml}#$tcname\" title=\"Click to see Pass/Fail history\">Pass/Fail</a>:<font color=\"$color[$colorIndex]\"> <a href=\"file:///$SvrDrive/$SvrProjName/$reportHtml\" onClick=\"RunFile('$scriptName -drive $SvrDrive -projName $SvrProjName -tcNamePatternExec $dirRoot\\\\b')\"  title=\"$TCCtrToolTip\">%5d$CtrSeparator<marquee width=48 direction=right behavior=alternate loop=10000 scrollamount=$TCScrollAmount>%-5d</marquee></a></font> AvgRespTime: %-10.2f     <font color=\"black\"> TimeSpan: %20s -- %20s       %s </font></span></li>\n",
                    $tcname,
                    $passCtr,
                    $failCtr,
                    $avgResponseTime,
                    &UnixDate( $timeSpanStart, "%Y %m %d %H:%M:%S" ),
                    &UnixDate( $timeSpanEnd,   "%Y %m %d %H:%M:%S" ),
		    $tcname.'/tc.pl',
                );
		if ($cmd =~ /noprint/i) {;} else { &appendtoFile( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1, $tmp );}
     	close Fin;
     	if ($returnValue) {$returnValue =~ s/^\s*//g;} else {$returnValue = "";} 
     	return $returnValue;
}


################################################################################
#	Subroutine Name : process Test Case
#		Function: wrapper for Test Case management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyO/proc
################################################################################
sub processTC {
	    my $tcOP = ''; my $tcname; my $cmd="";
	    shift; $tcOP= shift; 
	    my $prMsg = '' ; $prMsg= shift if @_;

	    $tcOP =~ /\s*([\w|\d]+)\s*(=)?\s*(\w+)?\s*(;)?(\s*\S+\s*)?/;  
	    $tcOP = $1; $tcname = $3; $cmd = $5;
	    #   if (($cmd) && ($cmd =~ /pr2Screen\s*=\s*1/)){ $prMsg = 1;}
	$prMsg = $pr2Screen;
	    $tcname =  &getTCName($tcname); 
	    my $rst; 
	    if ( $tcOP =~ /^\s*create/i ) {
		    if ($cmd) { $rst = &createTC("cmd=$cmd",$tcname); }
		    else { $rst = &createTC($tcname); }
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, $rst if $prMsg;
		    $rst = sprintf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, $rst;
		    return $rst;
            }
            elsif ( $tcOP =~ /^\s*exec\b/i ) {
		    $rst = &execTC($tcname);
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst if $prMsg;
		    $rst = sprintf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst ;
		    return $rst;
            }
            elsif ( $tcOP =~ /^\s*execAll/i ) {
		    $rst = &tcLoop();
		    return $rst;
            }
            elsif ( $tcOP =~ /^\s*log/i ) {
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  &logTC($tcname) if $prMsg;
		    &logTC($tcname);
            }
            elsif ( $tcOP =~ /^\s*detect/i ) {
		    $rst = &detectTC($tcname, $SvrProjName, $SvrDrive); 
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, $rst if $prMsg; 
		    $rst = sprintf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst ;
		    return $rst;
            }
            elsif ( $tcOP =~ /^\s*getLogName/i ) {
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, &getTCLogFname(&getTCName($tcname)) if $prMsg; 
		    return &getTCLogFname(&getTCName($tcname)); 
	    } elsif ( $tcOP =~ /^\s*list|get/i ) {
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'latest');
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst if $prMsg; 
		    $rst = sprintf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst ;
		    return $rst;
            }
            elsif ( $tcOP =~ /^\s*reportTCResult/i ) {
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, &reportTC($tcname,"","lastValue") ;
            }
            elsif ( $tcOP =~ /^\s*reportTCHistory/i ) {
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, &reportTCHistory($tcname);
            }
            elsif ( $tcOP =~ /^\s*delete/i ) {
		    $tcOP =~ s/^\s*delete\s*=//g;
		    $tcOP =~ s/\s*$//g;
		    $rst = &deleteTC($tcname);
		    printf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname, $rst if $prMsg; 
		    $rst = sprintf "\n%20s:%30s %s", "processTC ($tcOP)", $tcname,  $rst ;
		    return $rst;
            }
	    1;
}

sub createTC {
	my $cmd='';
	$cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
	my $tcNameRoot = "@_";
	my $tcName = &getTCName(@_);
	if( &detectTC($tcName) && ($cmd !~ /Overwrite/i)) {
		;} else 
	{
		mkpath($tcName);
		if ($cmd =~ /PerformanceTC/i) { 
		&createFile( $tcName.'\\'.'tc.pl', "\$| = 1; print \"1234567.89\\n\"; sleep 3; ");
		} elsif ($cmd =~ /FailedTC/i) {
		&createFile( $tcName.'\\'.'tc.pl', "\$| = 1; print \"fail\\n\"; sleep 3; ");
		} else {
		&createFile( $tcName.'\\'.'tc.pl', "\$| = 1; print \"pass\\n\"; sleep 3; ");
		}
        	&createPropertyTemplate($tcName);
		my $tmp =<<EOF;
open Fout, '>$tcName\\_tcLogAppend.txt';
print Fout "This is append log file";
close Fout;
exit;
EOF
		if (($cmd =~ /genLog/i) || ($cmd =~ /addLog/i)) {&appendtoFile( $tcName.'\\'.'tc.pl', $tmp) ; undef $tmp; }
		#if ($cmd =~ /webUI/i) {
$tcName =~ s/\\/\\\\/g;
		$tmp =<<EOF;
`$scriptName -drive $SvrDrive -projName $SvrProjName -updateWeb $tcName,2`; 
`$tcName\\\\tc.pl`; 
`$scriptName -drive $SvrDrive -projName $SvrProjName -updateWeb $tcName,0`; 


EOF
$tcName =~ s/\\\\/\\/g;
		&createFile( $tcName.'\\'.'tc_.pl', $tmp);

		#}
	}
	return "$tcName is created";
}


sub execTC {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName\\tc.pl" ) { my $cmd     = "$tcName\\tc.pl"; $rst     = `$cmd`; 
		my $timeEnd= &getDate(); 
	       $rst =~ /(pass|fail|todo|[\d|.]+|\w+)$/i; $rst = $1; $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) {
		$rstStr .= "Performance Test ($rst) ";
	       } else {
	       $rstStr .= "Functional Test ($rst) ";
	       } 
	       $rstStr .= '|comment2'; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       }
       else {
		return "tcName: $tcName doesn't exist.\n";
       }

}
sub deleteTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = &getTCName(@_);
	rmtree $tcName;
	return "$tcName is deleted";
}

sub detectTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = '';
	$tcName = &getTCName(@_);
     	if (-e  $tcName) { return  -e $tcName; } else { return '';}
}

sub getTCName {
	my $SvrProjNameTmp; my $SvrDriveTmp;
	my $SvrTCNameTmp ;  $SvrTCNameTmp = shift if @_; 
			if ($SvrTCNameTmp) {;} else { $SvrTCNameTmp = $SvrTCName; }  
			if ($SvrProjNameTmp) {;} else {  $SvrProjNameTmp = $SvrProjName;}  
			if ($SvrDriveTmp) {;} else {  $SvrDriveTmp = $SvrDrive;}  
	if ($SvrTCNameTmp =~ /$SvrDrive/i) {
		return  $SvrTCNameTmp;
	} else {
		return ($SvrDriveTmp.'\\'.$SvrProjNameTmp.'\\'.$SvrTCNameTmp) ;
	}
}

sub tcAvgResponseTime { # absolete
		my $tcname = shift; if ($tcname) {;} else {print "tcAvgResponseTime lack TCname\n";}
 		my $rst= &reportTC1(&getTCName($tcname),"","history")."\n";				
		@_ = split /\n/, $rst;
		my $ctr =0; my $totalTime =0; # in sec
		for (my $i=0; $i<=$#_; $i++) {
			$_[$i] =~ /^\s*(\w+)\s+(\w+)\s+/;
			my $tmp1 = $2;
			$tmp1 =~ s/s\s*$//g;
			$totalTime = $totalTime + $tmp1; $ctr++; 
		}
		if ($ctr == 0) { return '0.00'; }
		else { return sprintf "%.2f",$totalTime/$ctr;}
}


################################################################################
#	Subroutine Name : processProperty
#		Function: wrapper for property management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyOp
################################################################################
sub processProperty {
	    shift; my $tcname = shift; my $propertyOP = shift; my $rst=""; my $prMsg=0;
	    # print "pass ProcessProperty. c.perl.site.lib.test\n";
		if  ($tcname =~ /:|;/) { $propertyOP = $tcname; $tcname=&getTCName();}
		if ($propertyOP =~ /;\s*pr2Screen\s*=\s*\d+/) {
		$propertyOP =~ /;\s*pr2Screen\s*=\s*(\d+)\s*/; $prMsg = $1;
		$propertyOP =~ s/;\s*pr2Screen\s*=\s*(\d+)\s*//;
		}

	    if ( $propertyOP =~ /^\s*add/i ) {
                &addProperty( &getTCName($tcname), $propertyOP );
            }
            elsif ( $propertyOP =~ /^\s*del/i ) {
                &deleteProperty( &getTCName($tcname), $propertyOP );
            }
            elsif ( $propertyOP =~ /^\s*reset/i ) {
                ;
            }    # copy to a backup and create a property file
            elsif ( $propertyOP =~ /^\s*modify/i ) {
                &modifyProperty( &getTCName($tcname), $propertyOP );
            }
            elsif ( $propertyOP =~ /^\s*get|list/i ) {
		    $propertyOP =~ s/^\s*get\s*=//g; $propertyOP =~ s/^\s*list\s*=//g;
		    if ($propertyOP =~ /;/ ) {
			    @_ = split /;/, $propertyOP ;
			    $rst = &getProperties(&getTCName($tcname), $_[0], $_[1]);
	    	    } else {
			    $rst = &getProperties(&getTCName($tcname), $propertyOP );
		    }
            }
            elsif ( $propertyOP =~ /^\s*create/i ) {
        	&createPropertyTemplate($tcname);
            }
            elsif ( $propertyOP =~ /^\s*match|filter/i ) {
		    $propertyOP =~ s/^\s*match\s*=//g;
		    $propertyOP =~ /\s*(\S)\s*[:|;]\s*(\S)\s*/; 
        	    $rst = &matchProperty($1, $2, $tcname);
            } else {
	    	    $rst = sprintf "ProcessProperty (no match) %40s %20s", $tcname, $propertyOp;
    	    }
	    if ($rst =~ /^\s*$/) { $rst = "_noMatch_";}
	    if ($prMsg != 0) { print $rst;}
	    return $rst;
}

################################################################################
#	Subroutine Name : matchProperties
#		Function: return true/false 
#	Input Parameters: Property Name in regExp  
#	Output/Returns  : True/False
################################################################################
sub matchProperty { # &matchProperty("QAOwner","ywang", "TC_tc1");
	my $propertyName = "QAOwner"; my $propertyPattern = "ywangb"; my %array; my $tcname = "TC_tc1";
	if ($_[0]) { $propertyName = $_[0];}
	if ($_[1]) { $propertyPattern= $_[1];}
	if ($_[2]) { $tcname = $_[2];}

	 if (&getProperties(&getTCName($tcname)) =~ /info:There is no/ ) {
		 return "False";
	 }
	foreach my $each (split /\n/,  &getProperties(&getTCName($tcname))) {
		$each =~ /^\s*(\w+)\s*=\s*(\w+)\s*$/;
		$array {$1}  = $2;
	}
# todo: properytNamePattern is not used here print "pa: $propertyName, $propertyPattern\n";  
	foreach my $each (sort keys %array) {
		if (($array{$each} =~ /$propertyPattern/) && ( $each =~ /$propertyName/)) { 
			 return "True"; }
	}
	return 'False';
}

################################################################################
#	Subroutine Name : getProperties
#		Function: return Test Case Property
#	Input Parameters: Property Name (regExp)  (tcName, tcPattern, value)
#	Output/Returns  : Property Value
################################################################################
sub getProperties() { 	# get TC Property Names	(TH:TC Managements)
    my %array; my $returnValue = ""; my $propertyPattern = ''; my $tcname=''; my $returnType='';
    if ($_[0]) {$tcname = $_[0];}
    if ($_[1]) {$propertyPattern = $_[1];}
    if ($_[2]) {$returnType = $_[2];} # option = single, value, latest
    if ( -e  "$_[0]\\thProperty.txt" ) { ; } else { return "info:There is no $_[0]/thProperty.txt";}
    open Fin, "$_[0]\\thProperty.txt" || die "Can't open file:$!";
    while ( $_ = <Fin> ) {
        if ( $_ =~ /^\s*(\S+)\s*\|\s*(\S+)\s*\|/i ) {
		# if ( $_ =~ /^\s*(\w+)\|\s*(\w+)\s*\|/i ) { #todo
	      my $propertyName_ = $1; my $propertyValue_ = $2;

 	      if (($propertyName_ =~ /$propertyPattern/) || ( $propertyPattern eq '')) { # PropertyPattern Filter
  		if ($returnType =~ /^\s*$/) { $returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; }
  		elsif ($returnType =~ /value/i) { 
			$returnValue .= sprintf "%s\n", $propertyValue_;
  		}
  		elsif ($returnType =~ /history/i) { 
			$returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_;
  		}
  		elsif ($returnType =~ /latest/i) {$returnValue = "$propertyValue_\n";
  		}
  	       }
	       $array{$propertyName_} = $propertyValue_;
	}
        }
    close Fin;
      if ( $returnType =~ /latest/i) {
	      $returnValue = "";
      foreach my $each ( sort keys %array ) {
   	      if (($each =~ /$propertyPattern/) || ( $propertyPattern eq '')) { # PropertyPattern Filter
   		if ($returnType =~ /^\s*$/) { 
			# $returnValue .= sprintf "%-20s=%s\n",$each,$array{$each}; 
			;
		} elsif ($returnType =~ /value|history/i) { 
			#$returnValue .= "$array{$each}\n";
			;
   		} elsif ($returnType =~ /latest/i) {
			$returnValue .= sprintf "%-20s=%s\n",$each, $array{$each};
			# $returnValue = "$array{$each}\n";
   		}
   		}
       }
       }
    $returnValue =~ s/\s*\n\s*$//g;
    if ($returnValue =~ /^\s*$/) { $returnValue = "_noMatch_";}
    return $returnValue;
}

################################################################################
#	Subroutine Name : modfyProperty
#		Function: modify Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
#	Subroutine Name : 
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub modifyProperty() { 	# modify TC Property (TH:TC Managements)
    my $tcname       = $_[0];
    my $propertyName = $_[1];
    $propertyName =~ s/^\s*modify\s*=\s*//g;
    $propertyName =~ /(\w+)\s*:\s*(\w+)\s*/;
    $propertyName = $1;
    my $propertyValue = $2;
    my $cmdStr        = "delete=$propertyName";
    &deleteProperty( $tcname, $cmdStr );
    $cmdStr = "add=$propertyName:$propertyValue";
    &addProperty( $tcname, $cmdStr );
}

################################################################################
#	Subroutine Name : deleteProperty
#		Function: delete Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : update c:\TC_*\thProperty.txt
################################################################################
sub deleteProperty() {	# delete TC Property	(TH:TC Managements)
    my $fname = "$_[0]\\thProperty.txt";
    my $fout  = $fname; $fout =~ s/\.txt/_Dumpster\.txt/;

    my $propertyName = $_[1]; $propertyName =~ s/^\s*del\S*\s*=\s*//g; $propertyName =~ s/:\s*\S*//;
    my %array ;
    open Fin, "$fname"; @_ = <Fin>; close Fin;

    open Fout, ">>$fout";
    foreach my $each (@_) {
        if ( $each =~ /^\s*$propertyName\s*\|/i ) { print Fout "$each"; }
    }
    close Fout;

    open Fout, ">${fname}" || die "Can't open $fname:$!";
    foreach my $each (@_) {
        if ( $each !~ /^\s*$propertyName\s*\|/i ) {
            print Fout "$each";
        }
    }
    close Fout;
}

################################################################################
#	Subroutine Name : createPropertyTemplate
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub createPropertyTemplate() { 	# create TC Property File (TH:TC Managements)
    my $timeStr = getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|Comment1|Comment2";
    my $fname = "@_\\thProperty.txt";
    open Fout, ">$fname";
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcDesc','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSCR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'QA','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'modolID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'priority','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'openSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcOwner','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'resultN','null',$timeStr;
    close Fout;
}

################################################################################
#	Subroutine Name : addProperty
#		Function: add Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
################################################################################
sub addProperty() { 	# add TC Property (TH:TC Managements)
    my $timeStr = &getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|comment1|comment2";
    my $fname        = "$_[0]\\thProperty.txt";
    my $propertyName = $_[1];
    $propertyName =~ s/^\s*add\s*=\s*//ig;
    open Fout, ">>$fname";
    	if ($propertyName =~ /\|/) { # for tcRunResult 
		$propertyName =~ /^\s*(\S+)\s*\|\s*(\S+)\s*\|(.+)\s*$/; 
        	printf Fout "%20s|%10s|%s\n",$1, $2,$3;
	} else {
		$propertyName =~ /^\s*(\S+):(\S+)\s*/; 
        printf Fout "%20s|%10s%s\n",$1, $2,$timeStr;
	}
    close Fout;
}

sub getGlobalVars { 
	my $return = <<EOF;
	\$SvrDrive 		= $SvrDrive
	\$SvrProjName 		= $SvrProjName
 	\$SvrTCName 		= $SvrTCName
 	\$SvrTCNamePattern 	= $SvrTCNamePattern
 	\$SvrTCNameExecPattern	= $SvrTCNameExecPattern
	\$tcOp			= $tcOp
	\$SvrPropNamePattern 	= $SvrPropNamePattern
	\$SvrPropValuePattern 	= $SvrPropValuePattern
	\$pr2Screen           	= $pr2Screen            
EOF
	return $return;
} 
sub setGlobalVars {
	shift;
	@_ = split /;/, shift;
	foreach my $each (@_) {
		$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/;
		my $varName = $1;
		my $varValue = $2;
		if ($varName =~ /SvrDrive/i) { $SvrDrive = $varValue; }
		if ($varName =~ /SvrProjName/i) { $SvrProjName = $varValue; }
		if ($varName =~ /SvrTCName\b/i) { $SvrTCName = $varValue; }
		if ($varName =~ /SvrTCNamePattern\b/i) { $SvrTCNamePattern = $varValue; 
				$SvrTCNameExecPattern = $SvrTCNamePattern;
		}
		
		if ($varName =~ /SvrTCNameExecPattern/i) { $SvrTCNameExecPattern = $varValue; }
		if ($varName =~ /tcOp/i) { $tcOp= $varValue; }
		if ($varName =~ /SvrPropNamePattern\b/i) { $SvrPropNamePattern= $varValue; }
		if ($varName =~ /SvrPropValuePattern/i)  { $SvrPropValuePattern= $varValue; }
		if ($varName =~ /pr2Screen/i)  { $pr2Screen= $varValue; }
	}
	1;
}

sub processTCSettings {
	shift;
	@_ = split /;/, shift;
	foreach my $each (@_) {
		if ((($each =~ /listVars/i) || ($each =~ /getVars/i))&& ($each !~ /=/)) { return &getGlobalVars();} 
		if (($each =~ /printVars/i) && ($each !~ /=/)) { print &getGlobalVars(); return 1;} 

		$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/;
		my $varName = $1; my $varValue = $2;
		if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) {
			if ($varName =~ /Drive/i) 		{ $SvrDrive = $varValue; }
			if ($varName =~ /ProjName/i) 		{ $SvrProjName = $varValue; }
			if ($varName =~ /TCName\b/i) 		{ $SvrTCName = $varValue; }
			if ($varName =~ /TCNamePattern\b/i) 	{ $SvrTCNamePattern = $varValue; }
			if ($varName =~ /TCNameExecPattern/i) 	{ $SvrTCNameExecPattern = $varValue; }
			if ($varName =~ /tcOp/i) 		{ $tcOp= $varValue; }
			if ($varName =~ /PropNamePattern/i)  	{ $SvrPropNamePattern= $varValue; }
			if ($varName =~ /PropValuePattern/i)  	{ $SvrPropValuePattern= $varValue; }

			if ($varName =~ /TestSuite/i) 		{ $SvrProjName = $varValue; }
			if ($varName =~ /TCNameFilter\b/i) 	{ $SvrTCNamePattern = $varValue; }
			if ($varName =~ /TCNameExecFilter/i) 	{ $SvrTCNameExecPattern = $varValue; }
			if ($varName =~ /PropNameFilter/i)  	{ $SvrPropNamePattern= $varValue; }
			if ($varName =~ /PropValueFilter/i)  	{ $SvrPropValuePattern= $varValue; }
			if ($varName =~ /pr2Screen/i)  { $pr2Screen= $varValue; }
		} else { return '';}
	}
	1;
}

sub help {

my $help=<<EOF;
$0 		-processTCSettings 
					Drive=c:;
					TestSuite=_testProj_;
					TCOp=list;
					TCName=TC_tcA1;
					TCNameFilter=.*;
					TCNameExecFilter=.*;
					PropNameFilter=.*;
					PropValueFilter.=.*;
					pr2Screen=0|1;
					getVars|listVars|printVars
		-processTC 
					create|list|get|exec|execAll|detect|delete|log|getLogName|reportTCResult|reportResultHistory

		-processProperty
					add|delete|list|get|modify|match|filter|create

		-help
		-prDriver

		Note: perl.pl -MTest::AutomationFramework -e 
EOF
	print $help;

	if (-e "taf.pl") {;} else {
	open Fout, ">taf.pl";
	print Fout &prDriver(1);
	close Fout;
	print " --> taf.pl\n";
	}

}


sub prDriver {

	my $driver=<<EOF;
use Test::AutomationFramework;
use Getopt::Long;
	GetOptions(
	    'processTCSettings=s'          => \\\$processTCSettings,			
	    'processTC=s'                  => \\\$processTC,		
	    'processProperty=s'            => \\\$processProperty,		
	    'help'                  	   => \\\$help,	
	    'prDriver'                     => \\\$prDriver,	
	);
\$TAF = new Test::AutomationFramework;
if (\$help) {\$TAF->help();}
if (\$prDriver) {\$TAF->prDriver();}
if (\$processTCSettings) { \$TAF->processTCSettings(\$processTCSettings);}
if (\$processProperty) 	{ \$TAF->processTC(\$processProperty);}
if (\$processTC) 	{ \$TAF->processTC(\$processTC);}

EOF
if (@_) { return $driver;} else { print $driver;}
}
################################################################################
#	Subroutine Name : getDate
#		Function: get current Datetime 
#	Input Parameters: 
#	Output/Returns  : currentDate in the format of 2010-10-02 12:11:22
################################################################################
sub getDate ( ) {	# 	TH:Generic Functions: get current Time (TH:Generic Functions)
    my ( $y, $m, $d, $hh, $mm, $ss ) = (localtime)[ 5, 4, 3, 2, 1, 0 ];
    $y += 1900;
    $m++;
    my $iso_sale_time =
      sprintf( "%d-%02d-%02d %02d:%02d:%02d", $y, $m, $d, $hh, $mm, $ss );
    $iso_sale_time;
}

################################################################################
#	Subroutine Name : appendtoFile
#		Function: append text to a file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFile() {  	# TH:Generic Functions: append to file (TH:Generic Functions)
    my $fname = $_[0];
    open Fout, ">>$fname";
    print Fout "$_[1]";
    close Fout;
}

################################################################################
#	Subroutine Name : appendtoFileFile
#		Function: append file1 to file2
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFileFile() {  	# TH:Generic Functions: append file to file (TH:Generic Functions)
    my $fname = $_[0]; my $fnameOUT = $_[1];
    open Fin, "$fname" || die "Can't open $fname:$!";
    while ($_ = <Fin>) {
    	&appendtoFile($fnameOUT, $_) if ($_ !~ /^\s*$/);
    }
    close Fin;
}

################################################################################
#	Subroutine Name : createFile
#		Function: create a new file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub createFile() {  	# TH:Generic Functions: create to file (TH:Generic Functions)
    my $fname = $_[0];
    open Fout, ">$fname";
    print Fout "$_[1]\n";
    close Fout;
}

################################################################################
#	Subroutine Name : readFile
#		Function: Read a file
#	Input Parameters: Filename 
#	Output/Returns  : String
################################################################################
sub readFile() {  	# TH:Generic Functions: read file (TH:Generic Functions)
    my $fname = $_[0];
    if ( -e $fname ) {
    open Fin, "$fname";
    @_ = <Fin>;
    close Fin;
    return "@_";
    } else { return "";}
}

sub getRoot {
	my $string = shift;
			@_ = split /\\|\//, $string; 
			return $_[$#_]; 
}


sub prHtml1 {
&createFile( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, '' );
my $tmp =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="20"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}
	</script>
</head>
<body OnLoad ="function1()">
<pre>
<p>
<h2> <a href="http://127.0.0.1//Trainings/">Test Automation Framework </h2> <font size ="2" </font> </a>
<a title=\"latest Test Result pass/fail = Green/Red\">L</a>            <a title=\"Test Case Naem\">TC Name</a>                       -Pass/Fail-    <a title=\"pass/fail counts\">Ctr</a>    Average ResponseTime         over time span   ( start Date time  --  end Date Time)           <a title=\"Manual command to exec TC\">-TC Exec Command-</a> </span>
EOF
&appendtoFile ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp);
}

sub prHtml2 {
my $tmp =<<EOF;
</pre></body>
</html>
<style type="text/css"> a { text-decoration:none} </style> 
EOF
 &appendtoFile( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp );
}

__END__
		TAF Function Summary  (Code Name: th.pl as of Sept 27, 2010)
------------------------------------------------------------------------------------------
TH Function Category     Function Name            Function Description
------------------------------------------------------------------------------------------
TH:TC Managements        logIsValid               Verify if a log is valid by comparing TC created T and log create T Commented Done 
TH:TC Managements        tcRunningYN              get the TC result Pass/Fail                                         Commented Done
TH:TC Managements        getProperty              get TC Property Names                                               Commented Done
TH:TC Managements        getPropertyValues        get TC Property Values                                              Commented Done
TH:TC Managements        deleteProperty           delete TC Property                                                  Commented Done
TH:TC Managements        addProperty              add TC Property                                                     Commented Done
TH:TC Managements        modifyProperty           modify TC Property                                                  Commented Done
TH:TC Managements        appendPropFile           append to TC Property File                                          Commented Done
TH:TC Managements        createPropFile           create TC Property File                                             Commented n/a
TH:TC Managements        readProperty             Read TC Property                                                    Commented n/a
TH:TC Managements        updateTCResultProperty   Update TC Property                                                  Commented n/a
TH:TC Managements        genTC                    Generate a HelloWorld TC                                            Commented Done

TH:TC Report             Report                   TC Report Function                                                  Commented Done
TH:TC Report             reportUpdateOnWeb        update TC Report on webUI                                           Commented 
TH:TC Report             logExist                 Determine if a log exists                                           Commented Done

TH:TC Execution          ReportAvgResponseTime    report TC Average Response Time                                     Commented n/a
TH:TC Execution          lastPassFail             get the latest TC Pass/Fail Result                                  Commented Done
TH:TC Execution          longivityPeriod          If the TC in LongivityPeriod                                        Commented 

TH:WebUI                 thWebUIUpdate            Update the webUI based on thProperty.txt                            Commented v2
TH:WebUI                 tcStatusHtmlSync         synchrinize the HTML with with TC Result                            Commented v2
TH:WebUI                 tcStatusHtml             Display the TCStatuse in Html format                                Commented v2
TH:WebUI                 rearrangeWebUI           Update webUI based on thProperty.txt                                Commented v2
TH:WebUI                 tcLog2Web                Update TC Log on webUI                                              Commented v2

TH:Concurrency Control   tcRunningYNOther         get the running TC Status for Concurrency Control.                  Commented v2          
TH:Concurrency Control   tcScheduledYNOther       get the scheduled TC for Concurrency Control.                       Commented v2
TH:Concurrency Control   tcQueue                  TC Queue function for Concurrency Control.                          Commented v2
TH:Concurrency Control   tcDeQueue                TC deQueue for Concurrency Control                                  Commented v2

TH:Email Notification    emailNotification        Process the Outlook email Notification Commands                     Commented v3  
TH:Conti. Integration    thBuzRule                Handle Continuous Integration                                       Commented v3

TH:Assist Functions      genTimeStr               time format function                         			      Commented	                                   
TH:Assist Functions      getIP                    TH:Generic Functions: get IP of local machine                       Commented 
TH:Assist Functions      genThProperty            generate TH property file                                           Commented  
TH:Assist Functions      printLibraryFun          print QTP Library Functions                                         Commented 
TH:Assist Functions      readTestHarnessCmdLine   read Test Harness Cmd Line args                                     Commented 
TH:Assist Functions      genQTPInputs             generate QTP Input files                                            Commented 
TH:Assist Functions      thPropertyUpdate         update TH property                                                  Commented 
TH:Assist Functions      prHelp_short             Print the short Help                                                Commented todo
TH:Assist Functions      prHelp                   print lengthy Help                                                  Commented 
TH:Assist Functions      genQTPDriver             Generic qtpDriver                                                   Commented 
TH:Assist Functions      genQTPLibrary            Generate QTP Library                                                Commented 
TH:Assist Functions      genCmd                   Generate the Test Harness ASP files                                 Commented 

TH:Generic Functions     appendtoFile             TH:Generic Functions: append to file                                Commented Done
TH:Generic Functions     createFile               TH:Generic Functions: create a file                                 Commented Done
TH:Generic Functions     getDate                  TH:Generic Functions: get current Time                              Commented Done
TH:Generic Functions     reverse                  TH:Generic Functions: reverse a Associate Array                     Commented            
TH:Generic Functions     strLen                   Generic Functon: return Str len                                     Commented            
TH:Generic Functions     decrCtr                  Decrease Ctr                                                        Commented            
TH:Generic Functions     incrCtr                  Increase Ctr                                                        Commented            
TH:Generic Functions     getCtr                   Get Ctr                                                             Commented 
TH:Generic Functions     getCurrentTime           TH:Generic Functions: getCurrentTime                                Commented 
TH:Generic Functions     getHost                  getHost function done by SZ Team Charlie and David                  Commented 
TH:Generic Functions     getHostFromIP            Get Host done by SZ Team Charlie and David                          Commented               
------------------------------------------------------------------------------------------


=head1 NAME
    	Test::AutomationFramework - Test Automation Framework  (TAF)

=head1 SYNOPSIS
	use Test::AutomationFramework
	my $TAF = new Test::AutomationFramework;
	$TAF->testOp(......);
	$TAF->propertyOp(......);

=head1 DESCRIPTION
	TAF manages automated test cases with test case setup, test case query, test case execution and 
	test reult reporting based on the concept of Test Property. 

=head2	User Level Operations 

	Test Automation Operations: 	tf.pl -testOP [create|list|delete|exec]
	Property        Operations: 	tf.pl -propertyOP [create|add|list|modify|delete]
	TC & Property   Operations: 	tf.pl -tcOP [create|list|delete|exec] -propertyOP [create|add|list|modify|delete]

=head2	Programmer Level Test Automation Operations 

	TAF defines an Automated Test Case as a script that returns pass, fail, number
	Test Case Format: [Drive:]\[projName]\[tcDefaultName]  e.g c:\testProj1\tc.pl (return pass|fail)
	TAF manages automated test case created by different computer languages 
	-defaultTCName 
	* Create an automated TC  for testProj1   TAF->testOp(create="c:","projName","tc.pl");
	* List      automated TCs of  testProj1   TAF->testOp(  list="c:","projName","tc.pl");
	* Delete    automated TCs of  testProj1   TAF->testOp(delete="c:","projName","tc.pl");
	* exec      automated TCs of  testProj1   TAF->testOp(  exec="c:","projName","tc.pl");
	  
=head2	Programmer Level Property Operations 

	TAF manages Automated Test Case by the concept of TC Property 
	* Set 1st TC1's QA Owner is Yong	TAF->propertyOP(create=QAOwner:Yong);
	* Set 2nd TC1's QA Owner is Joe     	TAF->propertyOP(   add=QAOwner:Joe);
	* Set TC2 as a smoke test 		TAF->propertyOP(create=TCType:SmokeTest);
	* Set TC3 as both a regresson testand a performance test TAF->propertyOP(create=TestType:Regression);
	* List Smoke Test Suite's TCs		TAF->propertyOP(list=TestType:SmokeTest*);
	* Execute smoke test suite 		TAF->propertyOP(list=TestType:SmokeTest*);
	* Report smoke test suite's latest results  	TAF->propertyOP(create=QAOwner:Yong);
	* Report smoke test suite's historical results 	TAF->propertyOP(create=QAOwner:Yong);
	* Set tc5 Status = inactive 		TAF->propertyOP(create=TCStatus:inactive);
	* Set all smoke tests with Status = Outdated TAF->propertyOP(create=TCStatus:outdated);
	* Delete all smoke tests 		TAF->propertyOP(tcType=SmokeTest);
	* List all TC Properties		TAF->PropertyOp(listProperties);
	* Delete TC Properties			TAF->PropertyOp(delete=TCType:SmokeTest);
	* defaultTCName = tc.pl

=head2	TAF reports test results on STDOUT and HTML 

	* List the lastest smoke test results		TAF->tcResult("Result")
	* List the historical function test results 	TAF->tcResult("Log");
	* List the historical function test results 	TAF->tcResult("HistoricalLog");
	* List the Yong's test result

=head2	Programmer Level Test Report Operations:

	* Record the TC log
	* Record the TC historical log
	* Generate Perl Driver tf.pl 

=head1  LICENSE
	This script is free software; you can redistribute it and/or modify it
	under the same terms as Perl itself.

=head1 AUTHOR
    	Yong Wang (ywangperl@gmail.com)

=cut;

1;



