#!/usr/bin/env python3

# A little tool to encrypt/decrypt git secrets. Kinda like password-store, but more purpose specific and portable.

import logging
import os
import sys
import subprocess

keys = [
    "63DFE737F078657CC8A51C00C29ADD73B3563D82", # q3k
    "482FF104C29294AD1CAF827BA43890A3DE74ECC7", # inf
    "F07205946C07EEB2041A72FBC60C64879534F768", # cz2
    "0879F9FCA1C836677BB808C870FD60197E195C26", # implr
]


logger = logging.getLogger(__name__)


def encrypt(src, dst):
    cmd = ['gpg' , '--encrypt', '--armor', '--batch', '--yes', '--output', dst]
    for k in keys:
        cmd.append('--recipient')
        cmd.append(k)
    cmd.append(src)
    subprocess.check_call(cmd)

def decrypt(src, dst):
    cmd = ['gpg', '--decrypt', '--batch', '--yes', '--output', dst, src]
    subprocess.check_call(cmd)


class SecretStoreMissing(Exception):
    pass


class SecretStore(object):
    def __init__(self, plain_root, cipher_root):
        self.proot = plain_root
        self.croot = cipher_root

    def exists(self, suffix):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)
        return os.path.exists(c) or os.path.exists(p)

    def plaintext(self, suffix):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)

        has_p = os.path.exists(p)
        has_c = os.path.exists(c)

        if has_c and has_p and os.path.getctime(p) < os.path.getctime(c):
            logger.info("Decrypting {} ({})...".format(suffix, c))
            decrypt(c, p)

        return p

    def open(self, suffix, mode, *a, **kw):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)
        if 'w' in mode:
            return open(p, mode, *a, **kw)

        if not self.exists(suffix):
            raise SecretStoreMissing("Secret {} does not exist".format(suffix))

        if not os.path.exists(p) or os.path.getctime(p) < os.path.getctime(c):
            logger.info("Decrypting {} ({})...".format(suffix, c))
            decrypt(c, p)

        return open(p, mode, *a, **kw)


def main():
    if len(sys.argv) < 3 or sys.argv[1] not in ('encrypt', 'decrypt'):
        sys.stderr.write("Usage: {} encrypt/decrypt file\n".format(sys.argv[0]))
        sys.stderr.flush()
        return 1

    action = sys.argv[1]
    src = sys.argv[2]

    if action == 'encrypt':
        encrypt(src, '-')
    else:
        decrypt(src, '-')

if __name__ == '__main__':
    sys.exit(main() or 0)
