"""Helper module for GPG signing"""
import os

import bb
import oe.utils

class LocalSigner(object):
    """Class for handling local (on the build host) signing"""
    def __init__(self, d):
        self.gpg_bin = d.getVar('GPG_BIN') or \
                  bb.utils.which(os.getenv('PATH'), 'gpg')
        self.gpg_path = d.getVar('GPG_PATH')
        self.gpg_version = self.get_gpg_version()
        self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpmsign")

    def export_pubkey(self, output_file, keyid, armor=True):
        """Export GPG public key to a file"""
        cmd = '%s --no-permission-warning --batch --yes --export -o %s ' % \
                (self.gpg_bin, output_file)
        if self.gpg_path:
            cmd += "--homedir %s " % self.gpg_path
        if armor:
            cmd += "--armor "
        cmd += keyid
        status, output = oe.utils.getstatusoutput(cmd)
        if status:
            raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' %
                                      (keyid, output))

    def sign_rpms(self, files, keyid, passphrase, digest, sign_chunk, fsk=None, fsk_password=None):
        """Sign RPM files"""

        cmd = self.rpm_bin + " --addsign --define '_gpg_name %s'  " % keyid
        gpg_args = '--no-permission-warning --batch --passphrase=%s' % passphrase
        if self.gpg_version > (2,1,):
            gpg_args += ' --pinentry-mode=loopback'
        cmd += "--define '_gpg_sign_cmd_extra_args %s' " % gpg_args
        cmd += "--define '_binary_filedigest_algorithm %s' " % digest
        if self.gpg_bin:
            cmd += "--define '__gpg %s' " % self.gpg_bin
        if self.gpg_path:
            cmd += "--define '_gpg_path %s' " % self.gpg_path
        if fsk:
            cmd += "--signfiles --fskpath %s " % fsk
            if fsk_password:
                cmd += "--define '_file_signing_key_password %s' " % fsk_password

        # Sign in chunks
        for i in range(0, len(files), sign_chunk):
            status, output = oe.utils.getstatusoutput(cmd + ' '.join(files[i:i+sign_chunk]))
            if status:
                raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % output)

    def detach_sign(self, input_file, keyid, passphrase_file, passphrase=None, armor=True):
        """Create a detached signature of a file"""
        import subprocess

        if passphrase_file and passphrase:
            raise Exception("You should use either passphrase_file of passphrase, not both")

        cmd = [self.gpg_bin, '--detach-sign', '--no-permission-warning', '--batch',
               '--no-tty', '--yes', '--passphrase-fd', '0', '-u', keyid]

        if self.gpg_path:
            cmd += ['--homedir', self.gpg_path]
        if armor:
            cmd += ['--armor']

        #gpg > 2.1 supports password pipes only through the loopback interface
        #gpg < 2.1 errors out if given unknown parameters
        if self.gpg_version > (2,1,):
            cmd += ['--pinentry-mode', 'loopback']

        cmd += [input_file]

        try:
            if passphrase_file:
                with open(passphrase_file) as fobj:
                    passphrase = fobj.readline();

            job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
            (_, stderr) = job.communicate(passphrase.encode("utf-8"))

            if job.returncode:
                raise bb.build.FuncFailed("GPG exited with code %d: %s" %
                                          (job.returncode, stderr.decode("utf-8")))

        except IOError as e:
            bb.error("IO error (%s): %s" % (e.errno, e.strerror))
            raise Exception("Failed to sign '%s'" % input_file)

        except OSError as e:
            bb.error("OS error (%s): %s" % (e.errno, e.strerror))
            raise Exception("Failed to sign '%s" % input_file)


    def get_gpg_version(self):
        """Return the gpg version as a tuple of ints"""
        import subprocess
        try:
            ver_str = subprocess.check_output((self.gpg_bin, "--version", "--no-permission-warning")).split()[2].decode("utf-8")
            return tuple([int(i) for i in ver_str.split('.')])
        except subprocess.CalledProcessError as e:
            raise bb.build.FuncFailed("Could not get gpg version: %s" % e)


    def verify(self, sig_file):
        """Verify signature"""
        cmd = self.gpg_bin + " --verify --no-permission-warning "
        if self.gpg_path:
            cmd += "--homedir %s " % self.gpg_path
        cmd += sig_file
        status, _ = oe.utils.getstatusoutput(cmd)
        ret = False if status else True
        return ret


def get_signer(d, backend):
    """Get signer object for the specified backend"""
    # Use local signing by default
    if backend == 'local':
        return LocalSigner(d)
    else:
        bb.fatal("Unsupported signing backend '%s'" % backend)
