#!/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(r'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)
