"""
GnuPG abstraction layer

Copyright (C) 2010-2020 Cr@ns <roots@crans.org>
Authors : Daniel Stan <daniel.stan@crans.org>
          Vincent Le Gallic <legallic@crans.org>
          Alexandre Iooss <erdnaxe@crans.org>
SPDX-License-Identifier: GPL-3.0-or-later
"""

import subprocess
import logging

import gpg

# Local logger
log = logging.getLogger(__name__)


def decrypt(ciphertext: str):
    """
    Return decrypted content
    """
    log.info("Decrypting using GnuPG")
    with gpg.Context() as c:
        plaintext, _, _ = c.decrypt(ciphertext.encode("utf-8"))
    return plaintext.decode("utf-8")


def encrypt(content: str, keys: []) -> str:
    """
    Return encrypted content for keys
    """
    log.info("Encrypting using GnuPG")
    with gpg.Context() as c:
        c.armor = True
        cipher, _, _ = c.encrypt(content.encode("utf-8"), keys)
    return cipher.decode("utf-8")


def receive_key(fpr: str):
    """
    Download key from fingerprint
    """
    full_command = ['gpg', '--recv-keys', fpr]
    log.info("Running `%s`" % " ".join(full_command))
    return subprocess.run(full_command)


def check_key_validity(key, email: str) -> bool:
    """
    Check key identities email and trust level
    Return true if can be trusted and we can encrypt
    """
    log.info("Checking %s key with email %s" % (key.fpr, email))

    if not key.can_encrypt:
        log.debug("Cannot encrypt for key %s" % key.fpr)
        return False

    for uid in key.uids:
        if email == uid.email and not uid.revoked and not uid.invalid \
                and uid.validity >= gpg.constants.validity.FULL:
            return True

    # no trusted valid uid were found
    log.debug("No trusted valid uid were found for this key")
    return False


def get_key_from_fingerprint(fpr):
    """
    Get GnuPG key by fingerprint
    """
    log.info("Getting key corresponding to %s" % fpr)
    with gpg.Context() as c:
        return c.get_key(fpr)