#!/usr/bin/env python

import argparse
import getdeveloperlib
import sys
import os


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('patches', metavar='P', type=argparse.FileType('r'), nargs='*',
                        help='list of patches (use - to read patches from stdin)')
    parser.add_argument('-a', dest='architecture', action='store',
                        help='find developers in charge of this architecture')
    parser.add_argument('-p', dest='package', action='store',
                        help='find developers in charge of this package')
    parser.add_argument('-f', dest='files', nargs='*',
                        help='find developers in charge of these files')
    parser.add_argument('-c', dest='check', action='store_const',
                        const=True, help='list files not handled by any developer')
    parser.add_argument('-e', dest='email', action='store_const',
                        const=True, help='only list affected developer email addresses')
    return parser.parse_args()


def __main__():
    args = parse_args()

    # Check that only one action is given
    action = 0
    if args.architecture is not None:
        action += 1
    if args.package is not None:
        action += 1
    if args.files:
        action += 1
    if args.check:
        action += 1
    if len(args.patches) != 0:
        action += 1
    if action > 1:
        print("Cannot do more than one action")
        return
    if action == 0:
        print("No action specified")
        return

    # getdeveloperlib expects to be executed from the toplevel buildroot
    # directory, which is one level up from this script
    os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))

    devs = getdeveloperlib.parse_developers()
    if devs is None:
        sys.exit(1)

    # Handle the check action
    if args.check:
        files = getdeveloperlib.check_developers(devs)
        for f in files:
            print(f)

    # Handle the architecture action
    if args.architecture is not None:
        for dev in devs:
            if args.architecture in dev.architectures:
                print(dev.name)
        return

    # Handle the package action
    if args.package is not None:
        for dev in devs:
            if args.package in dev.packages:
                print(dev.name)
        return

    # Handle the files action
    if args.files is not None:
        args.files = [os.path.abspath(f) for f in args.files]
        for dev in devs:
            for devfile in dev.files:
                commonfiles = [f for f in args.files if f.startswith(devfile)]
                if commonfiles:
                    print(dev.name)
                    break

    # Handle the patches action
    if len(args.patches) != 0:
        (files, infras) = getdeveloperlib.analyze_patches(args.patches)
        matching_devs = set()
        for dev in devs:
            # See if we have developers matching by package name
            for f in files:
                if dev.hasfile(f):
                    matching_devs.add(dev.name)
            # See if we have developers matching by package infra
            for i in infras:
                if i in dev.infras:
                    matching_devs.add(dev.name)

        if args.email:
            for dev in matching_devs:
                print(dev)
        else:
            result = "--to buildroot@buildroot.org"
            for dev in matching_devs:
                result += " --cc \"%s\"" % dev

            if result != "":
                print("git send-email %s" % result)


__main__()
