#!/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)""")

    parser.add_argument('-p', '--buildhistory-dir',
                        action='store',
                        dest='buildhistory_dir',
                        default='buildhistory/',
                        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):
        if args.buildhistory_dir == 'buildhistory/':
            cwd = os.getcwd()
            if os.path.basename(cwd) == 'buildhistory':
                args.buildhistory_dir = cwd

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