my $sep = $^O eq "MSWin32" ? "\\" : "/";

sub get_date {
	local ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	local $day = $mday;
	local $month = $mon+1;
	local $year = $year+1900;
	if ( length $month == 1 ) {
		$month = join( "", "0", $month);
	}
	if ( length $day== 1 ) {
		$day = join( "", "0", $day );
	}
	local $date = join( ".", $year,$month,$day );
	return $date;
}

sub gen_snapshot_id {
	if ( exists $_[0] && exists $_[1] ) {
		return $_[0] . get_date() . $_[1];
	}

	if ( exists $_[0] ) {
		return $_[0] . get_date();
	}
	return get_date();
}

sub create_release {

	die "Must provide parameter to create_release\n" unless (exists $_[0]);
	
	my $release_folder_name = $_[0];
	
	my $release_version = $release_folder_name;
	$release_version =~ s/^gs-?//;
	$release_version =~ s/rc\d$//;
	my $major_version = $release_version;
	$major_version =~ s/^(3|2).*/$1/;	
	$release_version =~ s/^($major_version)\.?(\d*).*/$1.$2/;
	my $rk = "rk".$major_version;
	
	my $release_version_extra;
	if ($release_folder_name =~ m/(rc\d)$/) {
		$release_version_extra = $1;
	}
	if ($release_folder_name !~ m/^gs/) { # prefix gs
		$release_folder_name = "gs".$release_folder_name;
	}
	my $release_dir = "$ENV{'DATA_DIR'}${sep}$release_folder_name";
	
	print "major_version: $major_version\n";
	print "version: $release_version\n";
	print "versionextra: $release_version_extra\n";
	print "release_folder_name: $release_folder_name\n";
	print "release_dir: $release_dir\n";
	
	print "about to clean up old snapshots (Ctrl-C to cancel)";
	local $| = 1;
	for ( my $i=0; $i<5; $i++ ) {
		print ".";
		sleep 1;
	}
	$| = 0;

	print "cleaning up previous release snapshot $release_dir\n";
	
	if(-d $release_dir) {
		if ( $^O eq "MSWin32" ) {
			system("rd /q /s \"$release_dir\"");
		} else {
			system("rm -rf \"$release_dir\"");
		}
	}
		
	print "creating the release dir\n";	
	mkdir $release_dir or die "couldn't create release directory\n";

	print "changing to the release dir\n";
	chdir $release_dir;

	#version property
 	print "setting up todays properties\n";
	`echo version:$release_version> $rk-build.properties`;

	if($release_version_extra) {
		`echo version-extra:$release_version_extra>> $rk-build.properties`;
	}	
	
	#processor propertylocal $| = 1;
	if ( $^O eq "darwin" ) {
		print "setting processor\n";
		if ( `uname -p` eq "i386" ) {
			`echo processor:intel>> $rk-build.properties`;
		} elsif ( `uname -p` eq "powerpc" ) {
			`echo processor:ppc>> $rk-build.properties`;
		} else {
			print "unable to determine processor type, using intel\n";
			`echo processor:intel>> $rk-build.properties`;
		}
	} elsif ( $^O eq "linux" ) {
	    # Running "uname -m" on new 32 bit VM returns "i86_64" too
	    # So to properly test for 32 bit, ensure that environment.pl
	    # didn't set $ENV{'GS_OPENSSL_HOST'} to "linux-generic32"
	    if(`uname -m` =~ m/64$/) {
		if(! exists $ENV{'GS_OPENSSL_HOST'} || $ENV{'GS_OPENSSL_HOST'} ne "linux-generic32") {
		    print "Setting linux architecture to 64 bit";
		    `echo x64:true>> $rk-build.properties`;
		}
	    }
	}

	#branch path property
	if ( $ENV{'branch_path'} ) {
		`echo branch.path:$ENV{'branch_path'}>> $rk-build.properties`;
	}

	#server.exe.location
	if ( $major_version eq "2" && exists $ENV{'SERVER_EXE_LOCATION'} ) {
		`echo server.exe.location:$ENV{'SERVER_EXE_LOCATION'}>> $rk-build.properties`;
	}

	print "creating the snapshot using $rk\n";
	system( $rk );
}

sub create {
	
	die "release_dir not set, cant create\n" unless $release_dir;

	print "about to clean up old snapshots (Ctrl-C to cancel)";
	local $| = 1;
	for ( my $i=0; $i<5; $i++ ) {
		print ".";
		sleep 1;
	}
	$| = 0;

	print "cleaning up previous snapshot\n";
	local $release_parent = dirname($release_dir);
	if ( $^O eq "MSWin32" ) {
		system("rd /q /s \"$release_parent\"");
	} else {
		system("rm -rf \"$release_parent\"");
	}

	print "creating the release dir\n";
	mkdir $release_parent or die "couldn't create release parent directory\n";
	mkdir $release_dir or die "couldn't create release directory\n";

	print "changing to the release dir\n";
	chdir $release_dir;

	#version property
 	print "setting up todays properties\n";
	`echo version:$snapshot_id> $rk-build.properties`;

	#processor propertylocal $| = 1;
	if ( $^O eq "darwin" ) {
		print "setting processor\n";
		if ( `uname -p` eq "i386" ) {
			`echo processor:intel>> $rk-build.properties`;
		} elsif ( `uname -p` eq "powerpc" ) {
			`echo processor:ppc>> $rk-build.properties`;
		} else {
			print "unable to determine processor type, using intel\n";
			`echo processor:intel>> $rk-build.properties`;
		}
	}

	#branch path property
	if ( $ENV{'branch_path'} ) {
		`echo branch.path:$ENV{'branch_path'}>> $rk-build.properties`;
	}

	#x64 bit property for linux, not darwin
	if ( $^O eq "linux" && $ENV{'x64'} ) {
	    `echo x64:true>> $rk-build.properties`;
	}

	#server.exe.location
	if ( exists $ENV{'SERVER_EXE_LOCATION'} ) {
		`echo server.exe.location:$ENV{'SERVER_EXE_LOCATION'}>> $rk-build.properties`;
	}

	print "creating the snapshot using $rk\n";
	system( $rk );

}

sub prepare_upload {
        print "preparing files for uploading\n";    

	my @munges = ();
	if ( exists $ENV{'munges'} ) {
		@munges = split(' ', $ENV{'munges'});
	}

	#copy products to a temporary folder, giving them their new names
	#if ( $^O ne "MSWin32" && -d "$release_dir${sep}uploads" ) {
	if ( -d "$release_dir${sep}uploads" ) {
		if( $^O eq "MSWin32" ) {
			#print STDERR "*** Running: rmdir /s /q \"$release_dir${sep}uploads\"\n";
			system( "rmdir /s /q \"$release_dir${sep}uploads\"" );			
		} else {
			system( "rm -rf '$release_dir${sep}uploads'" );
		}
	}
	mkdir "$release_dir${sep}uploads";

	my @files;
	if ( -d "$release_dir${sep}products" ) {
		@files = <$release_dir${sep}products${sep}*>;
	}
	push( @files, "$release_dir${sep}$rk.out" );

	for my $file ( @files ) {
		if ( -e $file ) {
			my $filename = basename($file);
			#munge
			for my $m ( @munges ) {
				$doit="\$filename =~ $m"; eval "$doit";
			}
			# copy to uploads folder
			print "Copying '" . basename($file) . "' to '$filename' in uploads folder\n";
			if( $^O =~ "linux|darwin" ) {
				system("cp \"$file\" \"${release_dir}${sep}uploads${sep}$filename\"");
			}
			else {
				system("copy \"$file\" \"${release_dir}${sep}uploads${sep}$filename\"");
			}
		}

	}

}

# want to make all systems the same. lets not do uploading as part of making a release.
sub old_upload {
# ssh too old inside lsb to upload to www-internal, so we do that in a separate step later
	# We use the upload-files-to-www-internal.sh script on linux systems now
	# The following is still left in as it appears to work for the mac
	
    if( $^O !~ "linux" ) {
	my $command = "";
	
	##my $out = `set`;
	##print "out = $out\n";
	#$command = "cd \"${release_dir}${sep}uploads\" && tar -c * | ";
	#$command .= ($^O eq "MSWin32" ? "plink" : "ssh");
	#$command .= " -T -i \"$ENV{'IDENTITY_FILE'}\" nzdl\@puka.cs.waikato.ac.nz";
	#print "$command\n";
	#system("$command");
	
	## for now, upload a copy to the new machine, later to replace puka
	#$command = "cd \"${release_dir}${sep}uploads\" && tar -c * | ";
	#$command .= ($^O eq "MSWin32" ? "plink" : "ssh");
	#$command .= " -T -i \"$ENV{'IDENTITY_FILE'}\" nzdl-gsorg\@wwwdev.greenstone.org";
	##print "$command\n";
	#system("$command");
	
	# also upload a copy to www-internal, which is the new wwwdev, and will replace puka.
	my $extraflags = ($^O eq "MSWin32" ? "f -" : "");
	$command = "cd \"${release_dir}${sep}uploads\" && tar -c$extraflags * | ";
	$command .= ($^O eq "MSWin32" ? "plink" : "ssh");
	#$command .= " -T -i \"$ENV{'IDENTITY_FILE_ED25519'}\" nzdl-gsorg\@www-internal.greenstone.org";
	$command .= " -T -i \"$ENV{'IDENTITY_FILE_ED25519'}\" nzdl\@www-internal.greenstone.org";
	
	# The command constructed works from the terminal but not through envi. Something about the environment
	# is conflicting with the tar.
	
	# The following command works, copied from Kathy's work in upload-www-internal-windows.pl and adjusted
	if($^O eq "MSWin32") {
		## WORKS (could add location of 7z.exe to environment.pl PATH):
		$command = "cd \"${release_dir}${sep}uploads\" && \"C:\\Program Files\\7-Zip\\7z\" a -an -ttar -so rk* Greenstone* | plink -T -i \"$ENV{'IDENTITY_FILE_ED25519'}\" nzdl\@www-internal.greenstone.org";
	}
	
	print "*** Running upload command: $command\n";
	#STDOUT->flush();
	my $result = system("$command");
	#print "*** GOT RESULT $result\n";
	#STDOUT->flush();
    }
}

# EMAILING DOESN'T WORK, as SMTP not setup on release-kit LSB machines

#sub xsend_mail_on_releasekit_fail {

    # first, create your message
    # use Email::MIME;
#     my $message = Email::MIME->create(
# 	header_str => [
# 	    From    => $ENV{'MONITOR_EMAIL'},
# 	    To      => $ENV{'MONITOR_EMAIL'},
# 	    Subject => 'Trial message',
# 	],
# 	attributes => {
# 	    encoding => 'quoted-printable',
# 	    charset  => 'ISO-8859-1',
# 	},
# 	body_str => "Email test!\n",
# 	);
    
#     # send the message
#     use Email::Sender::Simple qw(sendmail);
#     sendmail($message);

    # %mail = ( To      => $ENV{'MONITOR_EMAIL'},
# 	      From    => $ENV{'MONITOR_EMAIL'},
# 	      Message => "This is a test message"
# 	);
    
#     sendmail(%mail) or die $Mail::Sendmail::error;
    
#     print "OK. Log says:\n", $Mail::Sendmail::log;
#}

# EMAILING DOESN'T WORK, as SMTP not setup on release-kit LSB machines

# Copied from diffcol's task.pl into here
# Sending emails with perl: http://learn.perl.org/examples/email.html
# Sending email attachments with perl: http://www.perlmonks.org/?node_id=19430
# Sadly none of the packages are installed by default and use of MIME::Lite is discouraged
sub send_mail_on_releasekit_fail
{
    # email greenstone_team if build failed

    my $logfile="$release_dir${sep}$rk.out";
    my $finalLinesLogOutput=`tail -n 50 $logfile`;

    print STDERR "Checking if successful... \n";
    # using reverse index to search from bottom of tail output
    my $had_error = 0;

    if (rindex($finalLinesLogOutput, "BUILD FAILED") != -1) {
	# release-kit failed to build binary
	$had_error = 1;
    }
    elsif (rindex($finalLinesLogOutput, "BUILD SUCCESSFUL") != -1) {
	# SUCCESS!
	$had_error = 0; 
    }
    else {
	# saw neither BUILD FAILED nor BUILD SUCCESSFUL in tail of log output
	# Could be that building never completed, still want to be notified
	$had_error = 2;
    }


    if(!$had_error) {
	# everything fine, no need to email
	return;
    }


    print STDERR "Build had error code: $had_error\n";
    # let's send the last 200 lines of the log file to the user as email
    # 
    $finalLinesLogOutput=`tail -n 200 $logfile`;

    my $msg = "Last 200 lines in the log:\n$finalLinesLogOutput";
    my $subject = "Release-kit $release_dir failed"; # mentions OS, bitness, date
    
    # let's attach logfile besides	
    
    if($isWin) {	
	if($use_blat && $blat && $ENV{'GSDL_SMTP'}) {
	    # http://stackoverflow.com/questions/709635/sending-mail-from-batch-file
	    #blat -to user@example.com -server smtp.example.com -f batch_script@example.com -subject "subject" -body "body"
	    
	    # need to install blat on windows
	    $cmd = "$blat -to $ENV{'MONITOR_EMAIL'} -server $ENV{'GSDL_SMTP'} -f $ENV{'MONITOR_EMAIL'} -attach $logfile -subject \"$subject\" -body \"$msg\"";			
	    $result = system($cmd);	
	}
	else {
	    $result = 1; # status from running mail command is 0 if success, 1 if fail
	    print STDERR "********************************************\n";
	    if ($use_blat) {
		print STDERR "Need blat and SMTP set to send mail attachment\n" ;
	    } else {	
		print STDERR "Not set up to send mail on Windows\n";
	    }
	    print STDERR "Inspect release-kit build log at: $log_file\n";
	    print STDERR "********************************************\n";
	}
    } else { # linux

	# try using sendmail, since mutt is not installed on lsb
	# https://vitux.com/three-ways-to-send-email-from-ubuntu-command-line/
	# Sending attachment with sendmail is too involved, see
	#   https://unix.stackexchange.com/questions/223636/sendmail-attachment/223650
	#   https://askubuntu.com/questions/355823/sending-file-using-sendmail
	# Will just put the contents of the rk log file in the body.

	# read in all of logfile
	# https://stackoverflow.com/questions/206661/what-is-the-best-way-to-slurp-a-file-into-a-string-in-perl
	my $contents = do {local (@ARGV,$/) = $logfile; <>};
	my $email_path = "$release_dir${sep}email.txt";
	if (open(FOUT, '>:utf8', $email_path))
	{
	    print FOUT "Subject: $subject";
	    if($contents) {
		print FOUT $contents;
	    } else {
		print FOUT "Empty release kit building log: $logfile\n";
	    }
	    close(FOUT);
	    $cmd = "sendmail $ENV{'MONITOR_EMAIL'} < $email_path";
	    $result = system($cmd);
	}
	else
	{
	    print STDERR "WARNING: sendmail email attempt failed. Failed to open file for writing email msg:\n\t$email_path\n";	

	    # try using mutt to send email
	    my $status = system("command -v mutt > /dev/null 2>&1;"); #better way of doing "which mutt"
	    
	    if($status != 0) { # mutt doesn't exist, can't send attachments, so send simple email
		$cmd="echo '$message' | mail -s '$subject' $ENV{'MONITOR_EMAIL'}";
		
		print STDERR "********************************************\n";
		print STDERR "No mutt installed, unable to mail attachment\n";
		print STDERR "Inspect release-kit build log at: $logfile\n";
		print STDERR "********************************************\n";
	    } else {
		#$cmd = "bash -c \"echo '$message' | mutt -a $logfile -s 'subject' -- $ENV{'MONITOR_EMAIL'}\"";
		$cmd = "echo '$message' | mutt -a $logfile -s '$subject' -- $ENV{'MONITOR_EMAIL'}";
	    }	
	
	    # run the mail command
	    $result = system($cmd); #&run_and_print_cmd($cmd);
	}
    }
    
    
    if($result != 0) {
	print STDERR "*** Unable to send email: $?\n";
    }
    else {
	print STDERR "Sent mail with $logfile attached.\n";
    }

}
