#!/usr/bin/env python3

# bitbake-diffsigs / bitbake-dumpsig
# BitBake task signature data dump and comparison utility
#
# Copyright (C) 2012-2013, 2017 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import sys
import warnings

warnings.simplefilter("default")
import argparse
import logging
import pickle

sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))

import bb.tinfoil
import bb.siggen
import bb.msg

myname = os.path.basename(sys.argv[0])
logger = bb.msg.logger_create(myname)

is_dump = myname == 'bitbake-dumpsig'


def find_siginfo(tinfoil, pn, taskname, sigs=None):
    result = None
    tinfoil.set_event_mask(['bb.event.FindSigInfoResult',
                            'logging.LogRecord',
                            'bb.command.CommandCompleted',
                            'bb.command.CommandFailed'])
    ret = tinfoil.run_command('findSigInfo', pn, taskname, sigs)
    if ret:
        while True:
            event = tinfoil.wait_event(1)
            if event:
                if isinstance(event, bb.command.CommandCompleted):
                    break
                elif isinstance(event, bb.command.CommandFailed):
                    logger.error(str(event))
                    sys.exit(2)
                elif isinstance(event, bb.event.FindSigInfoResult):
                    result = event.result
                elif isinstance(event, logging.LogRecord):
                    logger.handle(event)
    else:
        logger.error('No result returned from findSigInfo command')
        sys.exit(2)
    return result


def find_siginfo_task(bbhandler, pn, taskname, sig1=None, sig2=None):
    """ Find the most recent signature files for the specified PN/task """

    if not taskname.startswith('do_'):
        taskname = 'do_%s' % taskname

    if sig1 and sig2:
        sigfiles = find_siginfo(bbhandler, pn, taskname, [sig1, sig2])
        if not sigfiles:
            logger.error('No sigdata files found matching %s %s matching either %s or %s' % (pn, taskname, sig1, sig2))
            sys.exit(1)
        elif sig1 not in sigfiles:
            logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig1))
            sys.exit(1)
        elif sig2 not in sigfiles:
            logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig2))
            sys.exit(1)
    else:
        sigfiles = find_siginfo(bbhandler, pn, taskname)
        latestsigs = sorted(sigfiles.keys(), key=lambda h: sigfiles[h]['time'])[-2:]
        if not latestsigs:
            logger.error('No sigdata files found matching %s %s' % (pn, taskname))
            sys.exit(1)
        sig1 = latestsigs[0]
        sig2 = latestsigs[1]

    latestfiles = [sigfiles[sig1]['path'], sigfiles[sig2]['path']]

    return latestfiles


# Define recursion callback
def recursecb(key, hash1, hash2):
    hashes = [hash1, hash2]
    hashfiles = find_siginfo(tinfoil, key, None, hashes)

    recout = []
    if not hashfiles:
        recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
    elif hash1 not in hashfiles:
        recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash1))
    elif hash2 not in hashfiles:
        recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash2))
    else:
        out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color)
        for change in out2:
            for line in change.splitlines():
                recout.append('    ' + line)

    return recout


parser = argparse.ArgumentParser(
    description=("Dumps" if is_dump else "Compares") + " siginfo/sigdata files written out by BitBake")

parser.add_argument('-D', '--debug',
                    help='Enable debug output',
                    action='store_true')

if is_dump:
    parser.add_argument("-t", "--task",
                        help="find the signature data file for the last run of the specified task",
                        action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))

    parser.add_argument("sigdatafile1",
                        help="Signature file to dump. Not used when using -t/--task.",
                        action="store", nargs='?', metavar="sigdatafile")
else:
    parser.add_argument('-c', '--color',
                        help='Colorize the output (where %(metavar)s is %(choices)s)',
                        choices=['auto', 'always', 'never'], default='auto', metavar='color')

    parser.add_argument('-d', '--dump',
                        help='Dump the last signature data instead of comparing (equivalent to using bitbake-dumpsig)',
                        action='store_true')

    parser.add_argument("-t", "--task",
                        help="find the signature data files for the last two runs of the specified task and compare them",
                        action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))

    parser.add_argument("-s", "--signature",
                        help="With -t/--task, specify the signatures to look for instead of taking the last two",
                        action="store", dest="sigargs", nargs=2, metavar=('fromsig', 'tosig'))

    parser.add_argument("sigdatafile1",
                        help="First signature file to compare (or signature file to dump, if second not specified). Not used when using -t/--task.",
                        action="store", nargs='?')

    parser.add_argument("sigdatafile2",
                        help="Second signature file to compare",
                        action="store", nargs='?')

options = parser.parse_args()
if is_dump:
    options.color = 'never'
    options.dump = True
    options.sigdatafile2 = None
    options.sigargs = None

if options.debug:
    logger.setLevel(logging.DEBUG)

color = (options.color == 'always' or (options.color == 'auto' and sys.stdout.isatty()))

if options.taskargs:
    with bb.tinfoil.Tinfoil() as tinfoil:
        tinfoil.prepare(config_only=True)
        if not options.dump and options.sigargs:
            files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1], options.sigargs[0],
                                      options.sigargs[1])
        else:
            files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1])

        if options.dump:
            logger.debug("Signature file: %s" % files[-1])
            output = bb.siggen.dump_sigfile(files[-1])
        else:
            if len(files) < 2:
                logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (
                    options.taskargs[0], options.taskargs[1]))
                sys.exit(1)

            # Recurse into signature comparison
            logger.debug("Signature file (previous): %s" % files[-2])
            logger.debug("Signature file (latest): %s" % files[-1])
            output = bb.siggen.compare_sigfiles(files[-2], files[-1], recursecb, color=color)
else:
    if options.sigargs:
        logger.error('-s/--signature can only be used together with -t/--task')
        sys.exit(1)
    try:
        if not options.dump and options.sigdatafile1 and options.sigdatafile2:
            with bb.tinfoil.Tinfoil() as tinfoil:
                tinfoil.prepare(config_only=True)
                output = bb.siggen.compare_sigfiles(options.sigdatafile1, options.sigdatafile2, recursecb, color=color)
        elif options.sigdatafile1:
            output = bb.siggen.dump_sigfile(options.sigdatafile1)
        else:
            logger.error('Must specify signature file(s) or -t/--task')
            parser.print_help()
            sys.exit(1)
    except IOError as e:
        logger.error(str(e))
        sys.exit(1)
    except (pickle.UnpicklingError, EOFError):
        logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files')
        sys.exit(1)

if output:
    print('\n'.join(output))
