#!/usr/bin/perl -w

use strict;
use warnings;

use SReview::Model::Event;
use Net::SSH::AuthorizedKeysFile;
use Net::SSH::AuthorizedKey;
use Getopt::Long;
use Pod::Usage;

use SReview::Config::Common;

die 'Need $HOME to be set!' unless exists($ENV{HOME});

my $config = SReview::Config::Common::setup;

my $eventname = $config->get('event');
my $action = "add";
my $oknodo = 0;
my $help = 0;
my $keyfile = undef;
my $bindir = $ENV{HOME} . "/bin";

GetOptions(
	"event|e=s" => \$eventname,
	"action|a=s" => \$action,
	"help" => \$help,
	"oknodo|o" => \$oknodo,
	"file|f=s" => \$keyfile,
) or pod2usage("command line invalid");

=head1 NAME

sreview-keys - manage keys in SReview's C<authorized_keys> file.

=head1 SYNOPSIS

  sreview-keys --event="event name" --action="add" --file=./id_rsa.pub
  sreview-keys -a "remove" --file=./id_rsa.pub

=head1 DESCRIPTION

sreview-keys is a simple tool to manage keys in an C<authorized_keys>
file so that when you run C<rsync> to sync input data to the SReview
master server, the files are written to that event's own input directory
(and not elsewhere).

The default event name is taken from the SReview configuration file (see
L<sreview-config>, or it can be overridden with C<--event> (alias:
C<-e>).

The default action is to add a key; to remove one, either edit the file,
or use the C<--action=remove> (alias: C<-a remove>) option.

=cut

if($help) {
	pod2usage(0);
}

if(!defined($keyfile)) {
	pod2usage("key file not specified");
}

if($action ne "add" && $action ne "remove") {
	print STDERR "Unknown action: $action\n";
	exit 1;
}

my $event = SReview::Model::Event->new(config => $config, name => $eventname);

my $akf = Net::SSH::AuthorizedKeysFile->new();
my $file = $config->get('authkeyfile');
$akf->read($file);

open KEY, "<", $keyfile;
my $mkey = "";
while(<KEY>) {
	chomp;
	$mkey .= $_;
}
close KEY;

$mkey = Net::SSH::AuthorizedKey->parse($mkey);

my @newkeys = ();

foreach my $key($akf->keys()) {
	if($key->fingerprint() eq $mkey->fingerprint()) {
		if($action eq "add") {
			if(!$oknodo) {
				print STDERR "The provided key already exists in the file! Please remove it first\n";
				exit 1;
			} else {
				print "Key already added, ignoring\n";
				exit 0;
			}
		} else {
			# don't add to @mkeys
			next;
		}
	}
	push @newkeys, $key;
}

if($action eq "add") {
	if(! -x "$bindir/rrsync") {
		print STDERR "E: please install rrsync as $bindir/rrsync, and make sure it's executable (hint: /usr/share/doc/rsync/scripts/rrsync.gz)";
		exit 1;
	}
	my $iglob = $config->get('inputglob');
	my @input = split('/', $iglob);
	my @dirs = ();
	foreach my $in(@input) {
		if($in =~ /\*/) {
			last;
		}
		push @dirs, $in;
	}
	$mkey->option("command", "$bindir/rrsync '" . join('/', @dirs, $event->inputdir) . "'", 1);
	$mkey->option("no-agent-forwarding", 1, 1);
	$mkey->option("no-port-forwarding", 1, 1);
	$mkey->option("no-pty", 1, 1);
	$mkey->option("no-user-rc", 1, 1);
	$mkey->option("no-X11-forwarding", 1, 1);
	push @newkeys, $mkey;
}

if(!defined($file)) {
	$file = $akf->path_locate;
}
$akf = Net::SSH::AuthorizedKeysFile->new(keys => \@newkeys, file => $file);
$akf->save();