#!/usr/bin/perl
use strict;
use Getopt::Std;
use LWP::UserAgent;
use Digest::MD5 qw(md5_hex);
use MIME::Base64;
use URI::Escape;
use Data::Dumper;
use File::Copy;

our $OK = 0;
our $WARNING = 1;
our $CRITICAL = 2;
our $UNKNOWN = 3;

our %opts;
our $verbose = 0;


sub main {

	my $global_db;
	my $local_db;
	my $local_db_old;
	my %files;
	my $request;
	my $ws_url = "https://#I#";
	my $relative_path = "/opmon/opscm/api/";
	my $ret = $OK;
	my $proto = "https";

	getopt('n:s:d:', \%opts);

	if ( !defined($opts{'n'}) ||
	     !defined($opts{'s'}) ) {
	
		return usage();
	
	}

	if (!defined($opts{'d'})) {
		$opts{'d'} = "	/usr/local/opmon/libexec/";
	}
	
	$verbose = 1 if (defined($opts{'v'}));

	$global_db = $opts{'d'}."scm-files.ini";
	l("opening $global_db for reading");
	if (!-f $global_db) {
		print "Unable to locate $global_db\n";
		return $UNKNOWN;
	}
	get_files($global_db,\%files,0);
	
	$local_db = $opts{'d'}."scm-files-local.ini";
	
	# old local config file name
	$local_db_old = $opts{'d'}."scm-local-files.ini";
	
	l("opening $local_db for reading");
	if (-f $local_db) {
		get_files($local_db,\%files,1);
	} else {
		if (-f $local_db_old) {
		    move($local_db_old, $local_db);
		} else {
		    l("\tno local configuration files");
		}
	}

	if ($opts{'s'} =~ m/^h.+$/) {
		$ws_url = $opts{'s'}.$relative_path;
	} else {
		$ws_url =~ s/#I#/$opts{'s'}/g;
		$ws_url .= $relative_path;
	}
	l("weburl: $ws_url");
	
	return send_files(\%files,$ws_url);
	
}


sub send_files {

	my $hash = shift;
	my $ws = shift;
	
	my %files = %{$hash};
	my %post;
	my $ret = $OK;
	my $content;
	my $file;
	my $md5_path;
	my $md5_content;
	my $ua;
	my $response;
	my $i = 0;
	my $unknown_files = "";
	my $str;

	foreach $file (keys %files) {
		
		l("reading $file");
		if ($files{$file} && ! -f ($file)) {
			l("\tthis file is mandatory but doesn't exist! setting exit code to $WARNING");
			$unknown_files .= $file." ";
			$ret = $WARNING;
			next;
		}
		
		if (! -f ($file)) {
			l("\tfile NOT found, continue.");
			next;
		}
			
		$md5_path = md5_hex($file);
	
		open(F,$file) or warn print "Ignoring($file) ";
		foreach(<F>) {
			$content .= $_;
		}
		close(F);
		
		$md5_content = md5_hex($content);
		$content = encode_base64($content,"");
		$file = uri_escape($file);
		
		# mount our json manually to avoid dependencies
		$post{'file['.$i.']'} = "";
		$post{'file['.$i.']'} .= "{";
		$post{'file['.$i.']'} .= "\"md5_path\":\"$md5_path\",";
		$post{'file['.$i.']'} .= "\"md5_content\":\"$md5_content\",";
		$post{'file['.$i.']'} .= "\"path\":\"$file\",";
		$post{'file['.$i.']'} .= "\"content\":\"$content\"";
		$post{'file['.$i.']'} .= "}";

		l("\tfile read");

		$content = "";
		
		$i++;
	
	}

	$post{'namespace'} = $opts{'n'};
	$post{'timestamp'} = time();

	if ($i == 0) {
		print "Empty audit files list\n";
		return $OK;
	}

	$ua = LWP::UserAgent->new;
	$ua->timeout(10);
	
	l("sending info to server...");
	$response = $ua->post($ws,[%post]);

	if (!$response->is_success) {
		print "Unable to connect to $ws";
		$ret = $CRITICAL;
	} else {
	
		if ($response->content =~ m/^{"status":"(\d+)","output":"(.+)"}$/) {
			l("weburl return:");
			l($response->content);
			$ret = $1 if ($1 > $ret);
			$str = uri_unescape($2);
			$str =~ s/\+/ /g;
			print $str;
		} else {
			l("webreturn:");
			l($response->content);
			print "Error on sync, unable to read return";
			$ret = $UNKNOWN;
		}
		
	}

	if ($ret != $OK && $unknown_files ne "") {
		print " Unable to locate files: $unknown_files";
	}
	
	print "\n";
	return $ret;

}

sub l {
	my $msg = shift;
	
	return if (!$verbose);
		
	print "[".gmtime(time())."] $msg\n";
	
}

sub get_files {

	my $db = shift;
	my $hash = shift;
	my $mandatory = shift;

	open(GLB,"<$db");
	while(<GLB>) {
		chomp($_);
		l("\t".$_." mandatory: $mandatory");
		$$hash{$_} = $mandatory
	}
	close(GLB);
	
}


sub usage {
	print "Usage: opscm -s SCM_SERVER_URI -n SCM_NAMESPACE -d CONFIG_DIR\n";
	print "-s SCM_SERVER_URI   - SCM server address. ex: 127.0.0.1, https://localhost\n";
	print "-n SCM_NAMESPACE    - Configuration repo namespace. ex: localhost, linux-server\n";
	print "-d CONFIG_DIR       - Base configuration directory. Default /usr/local/opmon/libexec/\n";
	print "-v                  - Verbose output.\n";

	return $UNKNOWN;
}

exit main();
