#!/usr/bin/env python

import argparse
import getdeveloperlib
import sys


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

    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:
        for dev in devs:
            for f in args.files:
                if dev.hasfile(f):
                    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__()
