#!/usr/bin/env python3
#
# Collects the recorded SRCREV values from buildhistory and reports on them
#
# Copyright 2013 Intel Corporation
# Authored-by:  Paul Eggleton <paul.eggleton@intel.com>
#
# SPDX-License-Identifier: GPL-2.0-only
#

import collections
import os
import sys
import optparse
import logging

def logger_create():
    logger = logging.getLogger("buildhistory")
    loggerhandler = logging.StreamHandler()
    loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
    logger.addHandler(loggerhandler)
    logger.setLevel(logging.INFO)
    return logger

logger = logger_create()

def main():
    parser = optparse.OptionParser(
        description = "Collects the recorded SRCREV values from buildhistory and reports on them.",
        usage = """
    %prog [options]""")

    parser.add_option("-a", "--report-all",
            help = "Report all SRCREV values, not just ones where AUTOREV has been used",
            action="store_true", dest="reportall")
    parser.add_option("-f", "--forcevariable",
            help = "Use forcevariable override for all output lines",
            action="store_true", dest="forcevariable")
    parser.add_option("-p", "--buildhistory-dir",
            help = "Specify path to buildhistory directory (defaults to buildhistory/ under cwd)",
            action="store", dest="buildhistory_dir", default='buildhistory/')

    options, args = parser.parse_args(sys.argv)

    if len(args) > 1:
        sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args[1:]))
        parser.print_help()
        sys.exit(1)

    if not os.path.exists(options.buildhistory_dir):
        sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % options.buildhistory_dir)
        parser.print_help()
        sys.exit(1)

    if options.forcevariable:
        forcevariable = ':forcevariable'
    else:
        forcevariable = ''

    all_srcrevs = collections.defaultdict(list)
    for root, dirs, files in os.walk(options.buildhistory_dir):
        dirs.sort()
        if '.git' in dirs:
            dirs.remove('.git')
        for fn in files:
            if fn == 'latest_srcrev':
                curdir = os.path.basename(os.path.dirname(root))
                fullpath = os.path.join(root, fn)
                pn = os.path.basename(root)
                srcrev = None
                orig_srcrev = None
                orig_srcrevs = {}
                srcrevs = {}
                with open(fullpath) as f:
                    for line in f:
                        if '=' in line:
                            splitval = line.split('=')
                            value = splitval[1].strip('" \t\n\r')
                        if line.startswith('# SRCREV = '):
                            orig_srcrev = value
                        elif line.startswith('# SRCREV_'):
                            splitval = line.split('=')
                            name = splitval[0].split('_')[1].strip()
                            orig_srcrevs[name] = value
                        elif line.startswith('SRCREV ='):
                            srcrev = value
                        elif line.startswith('SRCREV_'):
                            name = splitval[0].split('_')[1].strip()
                            srcrevs[name] = value
                if srcrev and (options.reportall or srcrev != orig_srcrev):
                    all_srcrevs[curdir].append((pn, None, srcrev))
                for name, value in srcrevs.items():
                    orig = orig_srcrevs.get(name, orig_srcrev)
                    if options.reportall or value != orig:
                        all_srcrevs[curdir].append((pn, name, value))

    for curdir, srcrevs in sorted(all_srcrevs.items()):
        if srcrevs:
            print('# %s' % curdir)
            for pn, name, srcrev in srcrevs:
                if name:
                    print('SRCREV_%s:pn-%s%s = "%s"' % (name, pn, forcevariable, srcrev))
                else:
                    print('SRCREV:pn-%s%s = "%s"' % (pn, forcevariable, srcrev))


if __name__ == "__main__":
    main()
