#!/usr/bin/env python2.7
#
# Copyright (c) 2018 Advanced Micro Devices, Inc.
# All rights reserved.
#
# For use for simulation and test purposes only
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Author: Brandon Potter


import subprocess
from collections import OrderedDict, defaultdict

class OrderedDefaultDict(OrderedDict, defaultdict):
    def __init__(self, default_factory=None, *args, **kwargs):
        super(OrderedDefaultDict, self).__init__(*args, **kwargs)
        self.default_factory = default_factory

def diff_files(upstream, feature, paths=[]):
    """Given two git branches and an optional parameter 'path', determine
    which files differ between the two branches. Afterwards, organize the
    files with a printer-friendly data structure.

    Returns: Dictionary of directories with their corresponding files
    """

    raw =  subprocess.check_output(
        [ "git", "diff", "--name-status", "%s..%s" % (upstream, feature),
        "--" ] + paths
    )

    path = [line.split('\t')[1] for line in raw.splitlines()]

    odd = OrderedDefaultDict(list)
    for p in path:
        direc = subprocess.check_output(["dirname", p]).strip() + "/"
        filename = subprocess.check_output(["basename", p]).strip()
        odd[direc].append("%s" % filename)

    return odd

def cl_hash(upstream, feature, path):
    """Given two git branches and full path, record the identifier hash
    for changesets which diff between the upstream branch and feature branch.
    The changesets are ordered from oldest to youngest changesets in the
    list.

    Returns: List of identifier hashes
    """

    raw = subprocess.check_output(
        [ "git", "log", "--oneline", "%s..%s" % (upstream, feature),
        "--", path ]
    )

    return [l.split()[0] for l in raw.splitlines()]

def _main():
    import argparse
    parser = argparse.ArgumentParser(
        description="List all changes between an upstream branch and a " \
                    "feature branch by filename(s) and changeset hash(es).")

    parser.add_argument("--upstream", "-u", type=str, default="origin/master",
                        help="Upstream branch for comparison. " \
                        "Default: %(default)s")
    parser.add_argument("--feature", "-f", type=str, default="HEAD",
                        help="Feature branch for comparison. " \
                        "Default: %(default)s")
    parser.add_argument("paths", metavar="PATH", type=str, nargs="*",
                        help="Paths to list changes for")

    args = parser.parse_args()

    odd = diff_files(args.upstream, args.feature, paths=args.paths)

    for key, value in odd.iteritems():
        print key
        for entry in value:
            print "    %s" % entry
            path = key + entry
            sha = cl_hash(args.upstream, args.feature, path)
            for s in sha:
                print "\t%s" % s
        print

if __name__ == "__main__":
    _main()
