package OVH::Bastion::Plugin::generateEgressKey;

# vim: set filetype=perl ts=4 sw=4 sts=4 et:
use common::sense;

use File::Basename;
use lib dirname(__FILE__) . '/../../../../../lib/perl';
use OVH::Result;
use OVH::Bastion;
use OVH::Bastion::Plugin qw{ :DEFAULT };

sub ask_passphrase {
    require Term::ReadKey;
    print "Please enter a passphrase for the private key that'll stay on the bastion (not echoed): ";
    Term::ReadKey::ReadMode('noecho');
    chomp(my $pass1 = <STDIN>);
    if (length($pass1) < 5) {

        # ssh-keygen will refuse
        print "\n";
        return R('ERR_PASSPHRASE_TOO_SHORT', msg => "Passphrase needs to be at least 5 chars");
    }
    print "\nPlease enter it again: ";
    chomp(my $pass2 = <STDIN>);
    print "\n";
    Term::ReadKey::ReadMode('restore');
    if ($pass1 ne $pass2) {
        return R('ERR_PASSPHRASE_MISMATCH', msg => "Passphrases don't match, please try again");
    }
    return R('OK', value => $pass1);
}

sub preconditions {
    my %params = @_;
    my $fnret;

    my ($self, $group, $algo, $size, $account, $sudo, $context) =
      @params{qw{  self   group   algo   size   account   sudo   context}};

    if (!$algo || !$context) {
        return R('ERR_MISSING_PARAMETER', msg => "Missing argument algo[$algo] or context[$context]");
    }

    if (!grep { $context eq $_ } qw{ group account }) {
        return R('ERR_INVALID_PARAMETER', msg => "Type should be group or account");
    }

    # check whether algo is supported by system
    $fnret = OVH::Bastion::is_allowed_algo_and_size(algo => $algo, size => $size, way => 'egress');
    $fnret or return $fnret;
    ($algo, $size) = @{$fnret->value}{qw{ algo size }};    # untaint

    # check preconditions if we're generating a key for a group
    if ($context eq 'group') {
        if (!$group || !$self) {
            return R('ERR_MISSING_PARAMETER', msg => "Missing 'group' or 'self' parameter");
        }
        $fnret = OVH::Bastion::is_valid_group_and_existing(group => $group, groupType => 'key');
        $fnret or return $fnret;
        my $keyhome    = $fnret->value->{'keyhome'};
        my $shortGroup = $fnret->value->{'shortGroup'};
        $group = $fnret->value->{'group'};

        $fnret = OVH::Bastion::is_group_owner(group => $shortGroup, account => $self, superowner => 1, sudo => $sudo);
        if (!$fnret) {
            return R('ERR_NOT_GROUP_OWNER',
                msg =>
                  "Sorry, you're not an owner of group $shortGroup, which is needed to manage its egress keys ($fnret)"
            );
        }

        return R(
            'OK',
            value => {
                group      => $group,
                shortGroup => $shortGroup,
                keyhome    => $keyhome,
                algo       => $algo,
                size       => $size,
                context    => $context
            }
        );
    }
    elsif ($context eq 'account') {
        if (!$account) {
            return R('ERR_MISSING_PARAMETER', msg => "Missing 'group' parameter");
        }
        $fnret = OVH::Bastion::is_bastion_account_valid_and_existing(account => $account);
        $fnret or return $fnret;

        return R('OK', value => {algo => $algo, size => $size, context => $context});
    }
    else {
        return R('ERR_INTERNAL');
    }
}

1;
