#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2011 The Chromium OS Authors.
#

"""See README for more information"""

from argparse import ArgumentParser
import importlib.resources
import os
import re
import sys
import traceback

if __name__ == "__main__":
    # Allow 'from patman import xxx to work'
    our_path = os.path.dirname(os.path.realpath(__file__))
    sys.path.append(os.path.join(our_path, '..'))

# Our modules
from patman import control
from patman import gitutil
from patman import project
from patman import settings
from patman import terminal
from patman import test_util
from patman import test_checkpatch
from patman import tools

epilog = '''Create patches from commits in a branch, check them and email them
as specified by tags you place in the commits. Use -n to do a dry run first.'''

parser = ArgumentParser(epilog=epilog)
parser.add_argument('-b', '--branch', type=str,
    help="Branch to process (by default, the current branch)")
parser.add_argument('-c', '--count', dest='count', type=int,
    default=-1, help='Automatically create patches from top n commits')
parser.add_argument('-e', '--end', type=int, default=0,
    help='Commits to skip at end of patch list')
parser.add_argument('-D', '--debug', action='store_true',
    help='Enabling debugging (provides a full traceback on error)')
parser.add_argument('-p', '--project', default=project.detect_project(),
                    help="Project name; affects default option values and "
                    "aliases [default: %(default)s]")
parser.add_argument('-P', '--patchwork-url',
                    default='https://patchwork.ozlabs.org',
                    help='URL of patchwork server [default: %(default)s]')
parser.add_argument('-s', '--start', dest='start', type=int,
    default=0, help='Commit to start creating patches from (0 = HEAD)')
parser.add_argument('-v', '--verbose', action='store_true', dest='verbose',
                    default=False, help='Verbose output of errors and warnings')
parser.add_argument('-H', '--full-help', action='store_true', dest='full_help',
                    default=False, help='Display the README file')

subparsers = parser.add_subparsers(dest='cmd')
send = subparsers.add_parser('send')
send.add_argument('-i', '--ignore-errors', action='store_true',
       dest='ignore_errors', default=False,
       help='Send patches email even if patch errors are found')
send.add_argument('-l', '--limit-cc', dest='limit', type=int, default=None,
       help='Limit the cc list to LIMIT entries [default: %(default)s]')
send.add_argument('-m', '--no-maintainers', action='store_false',
       dest='add_maintainers', default=True,
       help="Don't cc the file maintainers automatically")
send.add_argument('-n', '--dry-run', action='store_true', dest='dry_run',
       default=False, help="Do a dry run (create but don't email patches)")
send.add_argument('-r', '--in-reply-to', type=str, action='store',
                  help="Message ID that this series is in reply to")
send.add_argument('-t', '--ignore-bad-tags', action='store_true',
                  default=False,
                  help='Ignore bad tags / aliases (default=warn)')
send.add_argument('-T', '--thread', action='store_true', dest='thread',
                  default=False, help='Create patches as a single thread')
send.add_argument('--cc-cmd', dest='cc_cmd', type=str, action='store',
       default=None, help='Output cc list for patch file (used by git)')
send.add_argument('--no-binary', action='store_true', dest='ignore_binary',
                  default=False,
                  help="Do not output contents of changes in binary files")
send.add_argument('--no-check', action='store_false', dest='check_patch',
                  default=True,
                  help="Don't check for patch compliance")
send.add_argument('--tree', dest='check_patch_use_tree', default=False,
                  action='store_true',
                  help=("Set `tree` to True. If `tree` is False then we'll "
                  "pass '--no-tree' to checkpatch (default: tree=%(default)s)"))
send.add_argument('--no-tree', dest='check_patch_use_tree',
                  action='store_false', help="Set `tree` to False")
send.add_argument('--no-tags', action='store_false', dest='process_tags',
                  default=True, help="Don't process subject tags as aliases")
send.add_argument('--no-signoff', action='store_false', dest='add_signoff',
                  default=True, help="Don't add Signed-off-by to patches")
send.add_argument('--smtp-server', type=str,
                  help="Specify the SMTP server to 'git send-email'")

send.add_argument('patchfiles', nargs='*')

test_parser = subparsers.add_parser('test', help='Run tests')
test_parser.add_argument('testname', type=str, default=None, nargs='?',
                         help="Specify the test to run")

status = subparsers.add_parser('status',
                               help='Check status of patches in patchwork')
status.add_argument('-C', '--show-comments', action='store_true',
                    help='Show comments from each patch')
status.add_argument('-d', '--dest-branch', type=str,
                    help='Name of branch to create with collected responses')
status.add_argument('-f', '--force', action='store_true',
                    help='Force overwriting an existing branch')

# Parse options twice: first to get the project and second to handle
# defaults properly (which depends on project)
# Use parse_known_args() in case 'cmd' is omitted
argv = sys.argv[1:]
args, rest = parser.parse_known_args(argv)
if hasattr(args, 'project'):
    settings.Setup(gitutil, parser, args.project, '')
    args, rest = parser.parse_known_args(argv)

# If we have a command, it is safe to parse all arguments
if args.cmd:
    args = parser.parse_args(argv)
else:
    # No command, so insert it after the known arguments and before the ones
    # that presumably relate to the 'send' subcommand
    nargs = len(rest)
    argv = argv[:-nargs] + ['send'] + rest
    args = parser.parse_args(argv)

if __name__ != "__main__":
    pass

if not args.debug:
    sys.tracebacklimit = 0

# Run our meagre tests
if args.cmd == 'test':
    from patman import func_test

    result = test_util.run_test_suites(
        'patman', False, False, False, None, None, None,
        [test_checkpatch.TestPatch, func_test.TestFunctional,
         'gitutil', 'settings', 'terminal'])

    sys.exit(0 if result.wasSuccessful() else 1)

# Process commits, produce patches files, check them, email them
elif args.cmd == 'send':
    # Called from git with a patch filename as argument
    # Printout a list of additional CC recipients for this patch
    if args.cc_cmd:
        fd = open(args.cc_cmd, 'r')
        re_line = re.compile('(\S*) (.*)')
        for line in fd.readlines():
            match = re_line.match(line)
            if match and match.group(1) == args.patchfiles[0]:
                for cc in match.group(2).split('\0'):
                    cc = cc.strip()
                    if cc:
                        print(cc)
        fd.close()

    elif args.full_help:
        with importlib.resources.path('patman', 'README.rst') as readme:
            tools.print_full_help(str(readme))
    else:
        # If we are not processing tags, no need to warning about bad ones
        if not args.process_tags:
            args.ignore_bad_tags = True
        control.send(args)

# Check status of patches in patchwork
elif args.cmd == 'status':
    ret_code = 0
    try:
        control.patchwork_status(args.branch, args.count, args.start, args.end,
                                 args.dest_branch, args.force,
                                 args.show_comments, args.patchwork_url)
    except Exception as e:
        terminal.tprint('patman: %s: %s' % (type(e).__name__, e),
                        colour=terminal.Color.RED)
        if args.debug:
            print()
            traceback.print_exc()
        ret_code = 1
    sys.exit(ret_code)
