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

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