#!/usr/bin/env python3

# Query which tasks will be restored from sstate
#
# Copyright 2016 Intel Corporation
# Authored-by:  Paul Eggleton <paul.eggleton@intel.com>
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import os
import subprocess
import tempfile
import shutil
import re

scripts_path = os.path.dirname(os.path.realpath(__file__))
lib_path = scripts_path + '/lib'
sys.path = sys.path + [lib_path]
import scriptpath
scriptpath.add_bitbake_lib_path()
import argparse_oe


def translate_virtualfns(tasks):
    import bb.tinfoil
    tinfoil = bb.tinfoil.Tinfoil()
    try:
        tinfoil.prepare(False)

        recipecaches = tinfoil.cooker.recipecaches
        outtasks = []
        for task in tasks:
            (mc, fn, taskname) = bb.runqueue.split_tid(task)
            if taskname.endswith('_setscene'):
                taskname = taskname[:-9]
            outtasks.append('%s:%s' % (recipecaches[mc].pkg_fn[fn], taskname))
    finally:
        tinfoil.shutdown()
    return outtasks


def check(args):
    tmpdir = tempfile.mkdtemp(prefix='oe-check-sstate-')
    try:
        env = os.environ.copy()
        if not args.same_tmpdir:
            env['BB_ENV_PASSTHROUGH_ADDITIONS'] = env.get('BB_ENV_PASSTHROUGH_ADDITIONS', '') + ' TMPDIR:forcevariable'
            env['TMPDIR:forcevariable'] = tmpdir

        try:
            cmd = ['bitbake', '--dry-run', '--runall=build'] + args.target
            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env)

            task_re = re.compile('NOTE: Running setscene task [0-9]+ of [0-9]+ \(([^)]+)\)')
            tasks = []
            for line in output.decode('utf-8').splitlines():
                res = task_re.match(line)
                if res:
                    tasks.append(res.group(1))
            outtasks = translate_virtualfns(tasks)
        except subprocess.CalledProcessError as e:
            print('ERROR: bitbake failed:\n%s' % e.output.decode('utf-8'))
            return e.returncode
    finally:
        shutil.rmtree(tmpdir)

    if args.log:
        with open(args.log, 'wb') as f:
            f.write(output)

    if args.outfile:
        with open(args.outfile, 'w') as f:
            for task in outtasks:
                f.write('%s\n' % task)
    else:
        for task in outtasks:
            print(task)

    return 0


def main():
    parser = argparse_oe.ArgumentParser(description='OpenEmbedded sstate check tool. Does a dry-run to check restoring the specified targets from shared state, and lists the tasks that would be restored. Set BB_SETSCENE_ENFORCE=1 in the environment if you wish to ensure real tasks are disallowed.')

    parser.add_argument('target', nargs='+', help='Target to check')
    parser.add_argument('-o', '--outfile', help='Write list to a file instead of stdout')
    parser.add_argument('-l', '--log', help='Write full log to a file')
    parser.add_argument('-s', '--same-tmpdir', action='store_true', help='Use same TMPDIR for check (list will then be dependent on what tasks have executed previously)')

    parser.set_defaults(func=check)

    args = parser.parse_args()

    ret = args.func(args)
    return ret


if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
