#!/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
from distutils.version import LooseVersion

# 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 LooseVersion(git.__version__) < '0.3.1':
        sys.stderr.write("Version of GitPython is too old, please install GitPython (python-git) 0.3.1 or later in order to use this script\n")
        sys.exit(1)

    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()
