#!/usr/bin/env python3

# Report significant differences in the buildhistory repository since a specific revision
#
# Copyright (C) 2013 Intel Corporation
# Author: Paul Eggleton <paul.eggleton@linux.intel.com>
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import os
import argparse

# Ensure PythonGit is installed (buildhistory_analysis needs it)
try:
    import git
except ImportError:
    print("Please install GitPython (python3-git) 0.3.4 or later in order to use this script")
    sys.exit(1)

def get_args_parser():
    description = "Reports significant differences in the buildhistory repository."

    parser = argparse.ArgumentParser(description=description,
                                     usage="""
    %(prog)s [options] [from-revision [to-revision]]
    (if not specified, from-revision defaults to build-minus-1, and to-revision defaults to HEAD)""")

    default_dir = os.path.join(os.environ.get('BUILDDIR', '.'), 'buildhistory')

    parser.add_argument('-p', '--buildhistory-dir',
                        action='store',
                        dest='buildhistory_dir',
                        default=default_dir,
                        help="Specify path to buildhistory directory (defaults to buildhistory/ under cwd)")
    parser.add_argument('-v', '--report-version',
                        action='store_true',
                        dest='report_ver',
                        default=False,
                        help="Report changes in PKGE/PKGV/PKGR even when the values are still the default (PE/PV/PR)")
    parser.add_argument('-a', '--report-all',
                        action='store_true',
                        dest='report_all',
                        default=False,
                        help="Report all changes, not just the default significant ones")
    parser.add_argument('-s', '---signatures',
                        action='store_true',
                        dest='sigs',
                        default=False,
                        help="Report list of signatures differing instead of output")
    parser.add_argument('-S', '--signatures-with-diff',
                        action='store_true',
                        dest='sigsdiff',
                        default=False,
                        help="Report on actual signature differences instead of output (requires signature data to have been generated, either by running the actual tasks or using bitbake -S)")
    parser.add_argument('-e', '--exclude-path',
                        action='append',
                        help="Exclude path from the output")
    parser.add_argument('-c', '--colour',
                        choices=('yes', 'no', 'auto'),
                        default="auto",
                        help="Whether to colourise (defaults to auto)")
    parser.add_argument('revisions',
                        default = ['build-minus-1', 'HEAD'],
                        nargs='*',
                        help=argparse.SUPPRESS)
    return parser

def main():

    parser = get_args_parser()
    args = parser.parse_args()

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

        sys.exit(1)

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

    scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
    lib_path = scripts_path + '/lib'
    sys.path = sys.path + [lib_path]

    import scriptpath

    # Set path to OE lib dir so we can import the buildhistory_analysis module
    scriptpath.add_oe_lib_path()
    # Set path to bitbake lib dir so the buildhistory_analysis module can load bb.utils
    bitbakepath = scriptpath.add_bitbake_lib_path()

    if not bitbakepath:
        sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
        sys.exit(1)

    if len(args.revisions) == 1:
        if '..'  in args.revisions[0]:
            fromrev, torev = args.revisions[0].split('..')
        else:
            fromrev, torev = args.revisions[0], 'HEAD'
    elif len(args.revisions) == 2:
        fromrev, torev = args.revisions

    from oe.buildhistory_analysis import init_colours, process_changes
    import gitdb

    init_colours({"yes": True, "no": False, "auto": sys.stdout.isatty()}[args.colour])

    try:
        changes = process_changes(args.buildhistory_dir, fromrev, torev,
                                  args.report_all, args.report_ver, args.sigs,
                                  args.sigsdiff, args.exclude_path)
    except gitdb.exc.BadObject as e:
        if not args.revisions:
            sys.stderr.write("Unable to find previous build revision in buildhistory repository\n\n")
            parser.print_help()
        else:
            sys.stderr.write('Specified git revision "%s" is not valid\n' % e.args[0])
        sys.exit(1)

    for chg in changes:
        out = str(chg)
        if out:
            print(out)

    sys.exit(0)

if __name__ == "__main__":
    main()
