#!/usr/bin/perl

use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
use Text::Diff;
use Term::Cap;
use Time::Local;

$| = 1;

my $THIS_FILE           =  ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory   =  ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
	$running_directory =~ s/^\./$ENV{PWD}/;
}

my $anvil = Anvil::Tools->new();

# Get a list of all interfaces with IP addresses.
$anvil->Get->switches({debug => 2, list => ["watch"]});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});


our $t = Term::Cap->Tgetent;

# One shot or continuous?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 
	'switches::watch' => $anvil->data->{switches}{watch},
}});
if ($anvil->data->{switches}{watch})
{
	# Do we have an interval?
	my $interval = 2;
	if ($anvil->data->{switches}{watch} =~ /^\d+$/)
	{
		$interval = $anvil->data->{switches}{watch};
	}
	$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { interval => $interval }});
	
	# Loop until terminated.
	while(1)
	{
		show_status($anvil);
		sleep $interval;
	}
}
else
{
	# Once and exit.
	show_status($anvil);
}

$anvil->nice_exit({exit_code => 0});


sub show_status
{
	my ($anvil) = @_;
	
	if ($anvil->data->{switches}{watch})
	{
		system('clear');
		print $t->Tgoto("cm", 0, 0);
	}
	
	if ($anvil->data->{switches}{watch})
	{
		my $date = $anvil->Get->date_and_time();
		print "-=] Updated: ".$date." - Press '<ctrl> + <c>' to exit\n";
	}
	
	my $vms                = {};
	my $longest_resource   = 3; # Res
	my $longest_connection = 2; # To
	my $longest_volume     = 3; # Vol
	my $total_transfer     = 0;

	my $root_directory = $anvil->data->{path}{directories}{resource_status};
	local(*DIRECTORY);
	opendir(DIRECTORY, $root_directory);
	while(my $file = readdir(DIRECTORY))
	{
		next if $file eq ".";
		next if $file eq "..";
		my $full_path = $root_directory."/".$file;
		if (-d $full_path)
		{
			my $resource = $file;
			if (length($resource) > $longest_resource)
			{
				$longest_resource = length($resource);
			}
			$vms->{resource}{$resource} = {};
			#print "Resource found: [".$resource."]\n";
		}
	}
	closedir(DIRECTORY);
	
	foreach my $resource (sort {$a cmp $b} keys %{$vms->{resource}})
	{
		my $directory = $root_directory."/".$resource."/connections";
		local(*DIRECTORY);
		opendir(DIRECTORY, $directory);
		while(my $file = readdir(DIRECTORY))
		{
			next if $file eq ".";
			next if $file eq "..";
			my $full_path = $directory."/".$file;
			if (-d $full_path)
			{
				my $connection = $file;
				if (length($connection) > $longest_connection)
				{
					$longest_connection = length($connection);
				}
				#print "Found connection: [".$resource."] -> [".$connection."]\n";
				$vms->{resource}{$resource}{connection}{$connection} = {};
			}
		}
		closedir(DIRECTORY);
	
		foreach my $connection (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}})
		{
			my $directory = $root_directory."/".$resource."/connections/".$connection;
			local(*DIRECTORY);
			opendir(DIRECTORY, $directory);
			while(my $file = readdir(DIRECTORY))
			{
				next if $file eq ".";
				next if $file eq "..";
				my $full_path = $directory."/".$file."/proc_drbd";
				if (-r $full_path)
				{
					my $volume = $file;
					if (length($volume) > $longest_volume)
					{
						$longest_volume = length($volume);
					}
					#print "Found volume: [".$resource."] -> [".$connection."] -> [".$volume."]\n";
					$vms->{resource}{$resource}{connection}{$connection}{volume}{$volume}{proc_drbd} = $full_path;
				}
			}
			closedir(DIRECTORY);
		}
	}

	print "Sync progress:\n";
	print "  ".sprintf("%-${longest_resource}s", "Res")."    ".sprintf("%-${longest_connection}s", "To")."    Vol\n";
	foreach my $resource (sort {$a cmp $b} keys %{$vms->{resource}})
	{
		foreach my $connection (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}})
		{
			foreach my $volume (sort {$a cmp $b} keys %{$vms->{resource}{$resource}{connection}{$connection}{volume}})
			{
				my $local_role = "";
				my $peer_role  = "";
				my $local_disk = "";
				my $peer_disk  = "";
				my $proc_file  = $vms->{resource}{$resource}{connection}{$connection}{volume}{$volume}{proc_drbd};
				my $progress = "";
				open (my $file_handle, "<", $proc_file) or die "Failed to read: [".$proc_file."], error: $!\n";
				while(<$file_handle>)
				{
					chomp;
					my $line = $_;
					if ($line =~ /ds:(.*?)\/(.*?) /)
					{
						$local_disk = $1;
						$peer_disk  = $2;
						if (($local_disk eq "UpToDate") && ($peer_disk eq "UpToDate"))
						{
							$progress = "(UpToDate)";
						}
					}
					if ($line =~ /ro:(.*?)\/(.*?) /)
					{
						$local_role = $1;
						$peer_role  = $2;
						if ($peer_role eq "Unknown")
						{
							$progress = "(Disconnected)";
						}
					}

					if ($line =~ /(\[.*?\])/)
					{
						$progress = $1." ";
					}
					if ($line =~ /sync'ed: (.*?\%)/)
					{
						$progress .= $1." ";
					}
					if ($line =~ /speed: (.*?) \(/)
					{
						my $speed          =  $1;
						   $progress       .= $speed." KiB/Sec ";
						   $speed          =~ s/\D//g;
						   $total_transfer += $speed;
					}
					if ($line =~ /finish: (.*?) speed/)
					{
						$progress .= "(ETA ".$1.")";
					}
				}
				close $file_handle;
				my $say_resource   = sprintf("%-${longest_resource}s", $resource);
				my $say_connection = sprintf("%${longest_connection}s", $connection);
				my $say_volume     = sprintf("%${longest_volume}s", $volume);
				print "- ".$say_resource." -> ".$say_connection." -> ".$say_volume.": ".$progress." //  ds:".$local_disk."/".$peer_disk.", ro:".$local_role."/".$peer_role."\n";
			}
		}
	}
	my $say_speed = $total_transfer / 1024;
	   $say_speed =~ s/^(\d+\.\d{3})\d+/$1/;
	print "* Total transfer speed is about: [".$say_speed." MiB/sec]\n";
}
