#!/usr/bin/perl
use IO::File;
use DB_File;
use Fcntl;
use Time::localtime;
use DateTime;
use Time::HiRes qw(gettimeofday);

#sub minutes ($$);
#sub secondsarray ($$);
#sub cpuinfo ($$);

##########Determine number of cores in system
my $coresdetected = 0;
open(CPUINFO, "/proc/stat") or return undef;
while(<CPUINFO>){
	chomp;
       	if(/^cpu\d+/)
       	{
		$coresdetected++;
	}
}
close(CPUINFO);
print "CORES detected: $coresdetected\n";
$coresdetected = --$coresdetected;
#print "decremented: $coresdetected\n";
##############################################


########creating and/or opening database
if (-e "/tmp/lscpulock")
{
	print "LOCKFILE /tmp/lscpulock detected!!!\n";
}else{
       	#create lock file
       	open lscpulock, ">/tmp/lscpulock";
	tie (%lscpu_db, DB_File, "/tmp/lscpu.db", O_CREAT|O_RDWR, 0644) ||
	die ("Cannot create or open /tmp/lscpu.db");
	my $num = 0;  
	if (exists $lscpu_db{"cpu$num"}) {
       		my $var = $lscpu_db{"cpu$num"};
       		$num = $var;
       		#my $test = $lscpu_db{"cpu$num"};
       		print "DB detected started where left off at entry $num\n";
       
       		#my $var2 = $lscpu_db{"cpu$var"};
       
       		#$var2 =~ /(.{3}\s+.{3}\s+\d{1,2}\s+.{8}\s+\d{4})/;
       		#print "Last entry was $var on $1\n";
	}else{
       		print "place holder key cpu0 does not exist. created!\n";
       		$lscpu_db{"cpu0"} = "$num";
	}
                      
	#close database
	untie(%lscpu_db);
       	#remove lock file
       	close lscpulock;
       	unlink "/tmp/lscpulock";
}

#CPU POLLING: 60 CPU POLLING: 60
my $success = 0;
if (-e "/var/www/cgi-bin/lsnet.conf")
{
       	open lsnetconf, "</var/www/cgi-bin/lsnet.conf";
       	while(<lsnetconf>)
       	{
               	chomp;
               	if(/^CPU\sPOLLING\:\s*(\d+)\s*$/)
               	{
			$frequency = $1;
			$success = 1; 
			print "success $frequency\n";
		}
      	}
	print "$success\n";
	if($success == 0) 
        {
               	print "ERROR: Wrong lsnet.conf format consult the instructions\n";
               	close lsnetconf;
               	exit;
        }

}
close lsnetconf;

main();


####### MAIN LOOP  WRITES 10 1MIN ENTRIES TO DB ONCE EVERY 10MIN
sub main{
	#my $frequency = initialize();
	#my $coresdetected = findcores();
	#my @passarray = ("$coresdetected" , "$frequency");
	my %value = ();
	my %tenarray = ();

	do{
		%tenarray = minutes();
        	if (-e "/tmp/lscpulock")
        	{
			print "LSCPULOCK FOUND\n";
        		for my $key ( keys %tenarray )
        		{
	        		$stupidvar = $key + $value{0};				
                		$value{"$stupidvar"} = $tenarray{"$key"};
			}
                	# 10 were added
                	$value{0} += 10;
		}else{
			writer(\%tenarray,\%value);
			#$value{0} = 0;
			my %value = ();
		}

	}while(1 == 1);
}

######### END MAIN LOOP

sub writer {
	my %tenarray = %{$_[0]};
	my %value = %{$_[1]};
	#sprintf("%d",$_[0]);
	#sprintf("%d",$_[0]);
	#my ($ref_one, $ref_two) = @_;
	#my (%coins) = $_[0];
	#my (%value) = $_[1];
	#create lock file
        open lscpulock, ">/tmp/lscpulock";
        #opening database
        tie (%lscpu_db, DB_File, "/tmp/lscpu.db") ||
        die ("Cannot open /tmp/lscpu.db");
	#my $firstele = $ref_two->[0];

        if (exists $value{0})
        {               
                for ($i = 1; $i <= $value{0}; $i++)
                {
                        $num = $lscpu_db{"cpu0"};
                        $num++;
			$lscpu_db{"cpu$num"} = $value{$i};
			$lscpu_db{"cpu0"} = "$num";
                }               
        }
        
	for ($i = 1; $i <= 10; $i++)
        {
		
                $num = $lscpu_db{"cpu0"};
                $num++;
		$lscpu_db{"cpu$num"} = $tenarray{$i};
                $lscpu_db{"cpu0"} = "$num";
        }
                        
        #close database
        untie(%lscpu_db);
        #remove lock file
        close lscpulock;
        unlink "/tmp/lscpulock";
        #print "DATABASE CLOSED\n";  
              
}

######## GRAB 10min WORTH OF DATA FROM SECONDSARRAY AND PUT IT INTO A hash
sub minutes {
        #my (%coins);
	my %coins = ();
	#my($coresdetected, $frequency) = (shift, shift);
	#my $coresdetected = $_[0];
	#my $frequency = $_[1];
        #my $coresdetected = sprintf("%d",$_[0]);
        #my $frequency = sprintf("%d",@_[1]);
	#@passarray
        #my $coresdetected = ${$_[0]};
	#my $frequency = ${$_[1]};
	#my $coresdetected = $_;
        $i = 1; #+ $backup;
        #$stopi = 10 + $backup;
        #print "in minutes sub! (every 10min) \n";
        #my @coins = ("test","test","test");
	#$cpuhash2{$mycore} = "$user $nice $system $idle $iowait $irq $softirq";
	#$coins{$i} = "";
        do {
                #my $date = $cpuhash2{"date"};
                #my $processes = $cpuhash2{"processes"};
		#$coins{$i} = "$date $processes";
		my %cpuhash2 = ();
                my(%cpuhash2) = secondsarray();
                my $date = $cpuhash2{"date"};
                my $processes = $cpuhash2{"processes"};
		$coins{$i} = "$date $processes";
                #print "string returned to minutes: $string\n";
	        for (my $mycore = 0; $mycore <= $coresdetected; $mycore++)
	        {
			$coins{$i} = $coins{$i} . "+" . "$cpuhash2{$mycore}"; 
                	#$coins[$mycore]->[$i] = "$cpuhash2{$mycore}";
			#$coins{"cpu$i"} = "$cpuhash2{$mycore}";
			#my $thisvar = $coins{"cpu$i"};
			#print "$imin $mycore $thisvar\n";
		}
		my $thisvar = $coins{$i}; 
		#$thisvar =~ s/^\+//;
		#$thisvar =~ s/^\s//;
		#$coins{$i} = "$thisvar";
		#my $thisvar = $coins{"$i"};
		print "$imin $thisvar\n";
		#$coins[processes]->[$i] = "$cpuhash2{processes}";
		#my $thisvar = $coins{"$mycorecpu$i"};
                #print "@coins";
                #print "printed from array: $coins{$i}\n";
                $i++;
        } while ($i<=10);
        return (%coins);
}
####### RETURN ARRAY TO MAIN LOOP


###### POLL CPUINFO EVERY 1 SEC FOR 1 MIN
sub secondsarray {
	my %cpuhash2 = ();

	my $poll = 60 / $frequency;
	print "POLL $poll\n";

        my $secs = 1;
	my $variable1 = 0;
	my %totalhash1 = ();
	my %totalhash2 = ();
	#total = user + nice + system + idle + iowait + irq + softirq
	my $user = 0;
	my $nice = 0;
	my $system = 0;
	my $idle = 0;
	my $iowait = 0;
	my $irq = 0;
	my $softirq = 0;
	my $processes = 0;
	my $processes2 = 0;

        #print "in secondsarray sub! (every 1 min) \n";
        do {
		my %cpuhash1 = ();
		my(%cpuhash1) = cpuinfo();
		my $walltime = $cpuhash1{"wall"};
		print "WALLTIME $walltime\n";
		#my $processes += $cpuhash1{"processes"};
		#my $date = 
        
		for (my $mycore = 0; $mycore <= $coresdetected; $mycore++)
		{
			$variable1 = $cpuhash1{$mycore};
			$variable1 =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/;
			$total = ($1 + $2 + $3 + $4 + $5 + $6 + $7);
			$user = ($1 / $total) * 100;
			$nice = ($2 / $total) * 100;
			$system = ($3 / $total) * 100;
			$idle = ($4 / $total) * 100;
			$iowait = ($5 / $total) * 100;
			$irq = ($6 / $total) * 100;
			$softirq = ($7 / $total) * 100;
                	 #print "TEST Core$mycore User: $user\%\n";
                	 #print "TEST Core$mycore Nice: $nice\%\n";
                	 #print "Core$mycore System: $system\%\n";
                	 #print "Core$mycore Idle: $idle\%\n";
                	 #print "Core$mycore IOWait: $iowait\%\n";
                	 #print "Core$mycore Irq: $irq\%\n";
                	 #print "Core$mycore SoftIrq: $softirq\%\n";
  	        	 #print "TESTING PROCS: $processes\n";
			$totalhash1[$mycore]->[$secs] = "$user $nice $system $idle $iowait $irq $softirq $walltime";
		}
		$processes2 += $cpuhash1{"processes"};
		#$processes = sprintf("%.2f", $processes);
                #my $processes += $cpuhash1{"processes"};
                $secs++;
        } while ($secs<=$poll);

	$processes = sprintf("%.2f", $processes2 / $poll);
	#$processes = $processes / 60;
	$user = 0;
	$nice = 0;
	$system = 0;
	$idle = 0; 
	$iowait = 0;
	$irq = 0;
	$softirq = 0;
	$walltime = 0;
	for (my $mycore = 0; $mycore <= $coresdetected; $mycore++)
        {
		$user = 0;
	        $nice = 0;
        	$system = 0;
       		$idle = 0;
        	$iowait = 0;
        	$irq = 0;
        	$softirq = 0;
        	$walltime = 0;
		#$processes = 0;

	        for ($secs = 1; $secs <= $poll; ++$secs)
		{
			#print "$totalhash1[$core]->[$secs]\n";
			$totalhash1[$mycore]->[$secs] =~ /(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)\s+(\d+.*\d*)/;
               		$user += $1; 
			$nice += $2; 			
			$system += $3;
			$idle += $4;
			$iowait += $5;
			$irq += $6;
			$softirq += $7;
			$walltime += $8;
			#$processes += $9;

		}
        	my $poll = $walltime / $frequency;
		$user = sprintf("%.2f", $user / $poll);
		$nice = sprintf("%.2f", $nice / $poll);
		$system = sprintf("%.2f", $system / $poll);
		$idle = sprintf("%.2f", $idle / $poll);
		$iowait = sprintf("%.2f", $iowait / $poll);
		$irq = sprintf("%.2f", $irq / $poll);
		$softirq = sprintf("%.2f", $softirq / $poll);
		#$processes = sprintf("%.2f", $processes / 60);
		#print "Core$core User: $user\%\n";
                #print "Core$core Nice: $nice\%\n";
                #print "Core$core System: $system\%\n";
                #print "Core$core Idle: $idle\%\n";
                #print "Core$core IOWait: $iowait\%\n";		
                #print "Core$core Irq: $irq\%\n";
                #print "Core$core SoftIrq: $softirq\%\n";
		#my $datetime = ctime();

		$cpuhash2{$mycore} = "$user $nice $system $idle $iowait $irq $softirq";
        }
	my $datetime = ctime();
	$cpuhash2{"processes"} = $processes;
	$cpuhash2{"date"} = $datetime;
        return (%cpuhash2);   
}
##### RETURN Average Load % per core and Average processes for past min



##### RETRIEVE CPU INFO
sub cpuinfo {
	my %cpuhash1 = ();
        #my(%cpuhash1);
        #my $coresdetected = ${$_[0]};
        #my $frequency = ${$_[1]};
	#        my $coresdetected = $_[0];
	#        my $frequency = $_[1];
        #my($coresdetected, $frequency) = (shift, shift); 
        #my($coresdetected, $frequency) = @_ ;
        #my $coresdetected = sprintf("%d",$_[0]);
        #my $frequency = sprintf("%d",$_[1]);
	my $processes1 = 0;
        open(CPUINFO, "/proc/stat") or return undef;
	my $one = gettimeofday;
        #print "in cpuinfo sub! (every second) \n";
        while(<CPUINFO>){
                chomp;
		for(my $mycore = 0; $mycore <= $coresdetected; $mycore++)
		{
                	if(/^cpu$mycore\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)
			{
				#cpu0 2138341 99106279 2579616 3297846 14535 9478 15344 0 0
                        	my $user = sprintf("%d",$1);
                                my $nice = sprintf("%d",$2);
                                my $system = sprintf("%d",$3);
                                my $idle = sprintf("%d",$4);
                                my $iowait = sprintf("%d",$5);
                                my $irq = sprintf("%d",$6);
                                my $softirq = sprintf("%d",$7);
				$string = "$user $nice $system $idle $iowait $irq $softirq";
				$cpuhash1{$mycore} = "$string";
                	}			
		}
        }
        close(CPUINFO);

	sleep($frequency);

        open(CPUINFO, "/proc/stat") or return undef;
	my $two = gettimeofday;
        while(<CPUINFO>){
                chomp;
                for(my $mycore = 0; $mycore <= $coresdetected; $mycore++)
                {
                        if(/^cpu$mycore\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)
                        {
                                #cpu0 2138341 99106279 2579616 3297846 14535 9478 15344 0 0
                                my $user = sprintf("%d",$1);
                                my $nice = sprintf("%d",$2);
                                my $system = sprintf("%d",$3);
                                my $idle = sprintf("%d",$4);
                                my $iowait = sprintf("%d",$5);
                                my $irq = sprintf("%d",$6);
                                my $softirq = sprintf("%d",$7);

                                $cpuhash1{"$mycore"} =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/;
				$user = $user - $1;
				$nice = $nice - $2;
				$system = $system - $3;
				$idle = $idle - $4;
				$iowait = $iowait - $5;
				$irq = $irq - $6;
				$softirq = $softirq - $7;
                                my $string2 = "$user $nice $system $idle $iowait $irq $softirq";
				$cpuhash1{$mycore} = $string2;
                        }                                
                }
        }
        close(CPUINFO);

	my $walltime = $two - $one;
	$cpuhash1{"wall"} = $walltime; #"0.000429868698120117"; 

	my $count = 0;
	my $directory = '/proc';
	for my $dir ($directory) 
	{
		opendir DIR, $dir or die "$dir: $!\n";
		while ($file = readdir DIR)
		{
			if ($file =~ /^\d+/)
			{
				++$count;
			}
		} 
		closedir DIR;
	}
	$cpuhash1{"processes"} = $count;
        return(%cpuhash1);
}
##### RETURN HASH FOR CPU INFO

