#!/usr/bin/env python3
"""
Add SSH keys

Add SSH keys to SSH agent.
The following keys are added: {keys}.

Usage:
    addsshkeys [options]

Options:
    -v, --verbose    list the keys as they are being added

A description of how to configure and use this program can be found at 
`<https://avendesora.readthedocs.io/en/latest/api.html#example-add-ssh-keys>_.
"""
# Assumes that the Avendesora account that contains the ssh key's passphrase 
# has a name or alias of the form <name>-ssh-key. It also assumes that the 
# account contains a field named 'keyfile' or 'keyfiles' that contains an 
# absolute path or paths to the ssh key files in a string.

from avendesora import PasswordGenerator
from inform import Inform, Error, codicil, conjoin, error, narrate
from docopt import docopt
from pathlib import Path
import pexpect

SSHkeys = 'personal work github backups'.split()
SSHadd = 'ssh-add'

cmdline = docopt(__doc__.format(keys = conjoin(SSHkeys)))
Inform(narrate=cmdline['--verbose'])

try:
    pw = PasswordGenerator()
except Error as e:
    e.terminate()

for key in SSHkeys:
    name = key + '-ssh-key'
    try:
        account = pw.get_account(name)
        passphrase = str(account.get_passcode().value)
        if account.has_field('keyfiles'):
            keyfiles = account.get_value('keyfiles').value
        else:
            keyfiles = account.get_value('keyfile').value
        for keyfile in keyfiles.split():
            path = Path(keyfile).expanduser()
            narrate('adding.', culprit=keyfile)
            try:
                sshadd = pexpect.spawn(SSHadd, [str(path)])
                sshadd.expect('Enter passphrase for %s: ' % (path), timeout=4)
                sshadd.sendline(passphrase)
                sshadd.expect(pexpect.EOF)
                sshadd.close()
                response = sshadd.before.decode('utf-8')
                if 'identity added' in response.lower():
                    continue
            except (pexpect.EOF, pexpect.TIMEOUT):
                pass
            error('failed.', culprit=key)
            codicil('response:', sshadd.before.decode('utf8'), culprit=SSHadd)
            if sshadd.exitstatus:
                codicil('exit status:', sshadd.exitstatus , culprit=SSHadd)
    except Error as e:
        e.terminate(culprit=key)
