#!/usr/bin/env python3
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Wrapper around the post-review/rbt tool provided by Review Board.

This script provides the ability to send one review for each
commit on the current branch, instead of squashing all changes
into a single large review. We encourage contributors to create
logical commits which can be reviewed independently.

Options to pass onto 'rbt' can be placed in a '.reviewboardrc'
file at the top of the Mesos source directory.  A default
'.reviewboardrc' can be found at 'support/reviewboardrc'.
Running './bootstrap' will populate this file for you.

To use this script, first install 'RBTools' from Review Board:
http://www.reviewboard.org/downloads/rbtools/

$ cd /path/to/mesos
$ [ do some work on your branch off of master, make commit(s) ]
$ ./support/post-reviews.py
"""
# pylint: skip-file

import argparse
import atexit
import imp
import os
import platform
import re
import sys
import urllib.parse

from distutils.version import LooseVersion

from subprocess import check_output, Popen, PIPE, STDOUT


def execute(command, ignore_errors=False):
    """Execute a process and leave."""
    process = None
    try:
        process = Popen(command,
                        stdin=PIPE,
                        stdout=PIPE,
                        stderr=STDOUT,
                        shell=False)
    except Exception:
        if not ignore_errors:
            raise
        return None

    data, _ = process.communicate()
    data = data.decode(sys.stdout.encoding)
    status = process.wait()
    if status != 0 and not ignore_errors:
        cmdline = ' '.join(command) if isinstance(command, list) else command
        need_login = 'Please log in to the Review Board' \
                     ' server at reviews.apache.org.'
        if need_login in data:
            print(need_login, '\n')
            print("You can either:")
            print("  (1) Run 'rbt login', or")
            print("  (2) Set the default USERNAME/PASSWORD in '.reviewboardrc'")
        else:
            print('Failed to execute: \'' + cmdline + '\':')
            print(data)
        sys.exit(1)
    elif status != 0:
        return None
    return data


def main():
    """Main function, post commits added to this branch as review requests."""
    # TODO(benh): Make sure this is a git repository, apologize if not.

    # Choose 'rbt' if available, otherwise choose 'post-review'.
    post_review = None

    rbt_command = 'rbt'
    # Windows command name must have `cmd` extension.
    if platform.system() == 'Windows':
        rbt_command = 'rbt.cmd'

    rbt_version = execute([rbt_command, '--version'], ignore_errors=True)
    if rbt_version:
        rbt_version = LooseVersion(rbt_version)
        post_review = [rbt_command, 'post']
    elif execute(['post-review', '--version'], ignore_errors=True):
        post_review = ['post-review']
    else:
        print('Please install RBTools before proceeding')
        sys.exit(1)

    # Warn if people have unstaged changes.
    diff_stat = execute(['git', 'diff', '--shortstat']).strip()

    if diff_stat:
        print('WARNING: Worktree contains unstaged changes, continuing anyway.', file=sys.stderr)

    # Warn if people have uncommitted changes.
    diff_stat = execute(['git', 'diff', '--shortstat', '--staged']).strip()

    if diff_stat:
        print('WARNING: Worktree contains staged but uncommitted changes, ' \
            'continuing anyway.', file=sys.stderr)

    # Grab a reference to the repo's git directory. Usually this is simply
    # .git in the repo's top level directory. However, when submodules are
    # used, it may appear elsewhere. The most up-to-date way of finding this
    # directory is to use `git rev-parse --git-common-dir`. This is necessary
    # to support things like git worktree in addition to git submodules.
    # However, as of January 2016, support for the '--git-common-dir' flag is
    # fairly new, forcing us to fall back to the '--git-dir' flag if
    # '--git-common-dir' is not supported. We do this by checking the output of
    # git rev-parse --git-common-dir` and check if it gives a valid directory.
    # If not, we set the git directory using the '--git-dir' flag instead.
    git_dir = execute(['git', 'rev-parse', '--git-common-dir']).strip()
    if not os.path.isdir(git_dir):
        git_dir = execute(['git', 'rev-parse', '--git-dir']).strip()

    # Grab a reference to the top level directory of this repo.
    top_level_dir = execute(['git', 'rev-parse', '--show-toplevel']).strip()

    # Use the tracking_branch specified by the user if exists.
    parser = argparse.ArgumentParser(add_help=True)
    parser.add_argument(
        '--server',
        help='Specifies the Review Board server to use.')
    parser.add_argument(
        '--no-markdown',
        action='store_true',
        help='Specifies if the commit text should not be treated as Markdown.')
    parser.add_argument(
        '--bugs-closed',
        help='The comma-separated list of bug IDs closed.')
    parser.add_argument(
        '--target-people',
        help='The usernames of the people who should perform the review.')
    parser.add_argument(
        '--tracking-branch',
        help='The remote tracking branch from which your local branch is derived.')
    args, _ = parser.parse_known_args()

    # Try to read the .reviewboardrc in the top-level directory.
    reviewboardrc_filepath = os.path.join(top_level_dir, '.reviewboardrc')
    if os.path.exists(reviewboardrc_filepath):
        # Prevent generation of '.reviewboardrcc'.
        sys.dont_write_bytecode = True
        reviewboardrc = imp.load_source('reviewboardrc', reviewboardrc_filepath)

    if args.server:
        reviewboard_url = args.server
    elif 'REVIEWBOARD_URL' in dir(reviewboardrc):
        reviewboard_url = reviewboardrc.REVIEWBOARD_URL
    else:
        reviewboard_url = 'https://reviews.apache.org'

    if args.tracking_branch:
        tracking_branch = args.tracking_branch
    elif 'TRACKING_BRANCH' in dir(reviewboardrc):
        tracking_branch = reviewboardrc.TRACKING_BRANCH
    else:
        tracking_branch = 'master'

    branch_ref = execute(['git', 'symbolic-ref', 'HEAD']).strip()
    branch = branch_ref.replace('refs/heads/', '', 1)

    # Do not work on the tracking branch.
    if branch == tracking_branch:
        print("We're expecting you to be working on another branch" \
              " from {}!".format(tracking_branch))
        sys.exit(1)

    temporary_branch = '_post-reviews_' + branch

    # Always delete the temporary branch.
    atexit.register(
        lambda: execute(['git', 'branch', '-D', temporary_branch], True))

    # Always put us back on the original branch.
    atexit.register(lambda: execute(['git', 'checkout', branch]))

    # Warn if the tracking branch is no direct ancestor of this review chain.
    if execute([
            'git', 'merge-base', '--is-ancestor', tracking_branch, branch_ref],
            ignore_errors=True) is None:
        print("WARNING: Tracking branch '%s' is no direct ancestor of HEAD." \
            " Did you forget to rebase?" % tracking_branch, file=sys.stderr)

        try:
            input("Press enter to continue or 'Ctrl-C' to abort.\n")
        except KeyboardInterrupt:
            sys.exit(0)

    merge_base = execute(
        ['git', 'merge-base', tracking_branch, branch_ref]).strip()

    output = check_output([
        'git',
        '--no-pager',
        'log',
        '--pretty=format:%Cred%H%Creset -%C'
        '(yellow)%d%Creset %s %Cgreen(%cr)%Creset',
        merge_base + '..HEAD'])

    print('Running \'%s\' across all of ...' % " ".join(post_review))
    sys.stdout.buffer.write(output)

    log = execute(['git',
                   '--no-pager',
                   'log',
                   '--no-color',
                   '--pretty=oneline',
                   '--reverse',
                   merge_base + '..HEAD']).strip()

    if len(log) <= 0:
        print("No new changes compared with master branch!")
        sys.exit(1)

    shas = []

    for line in log.split('\n'):
        sha = line.split()[0]
        shas.append(sha)

    previous = merge_base
    parent_review_request_id = None
    for i, sha in enumerate(shas):
        execute(['git', 'branch', '-D', temporary_branch], True)

        message = execute(['git',
                           '--no-pager',
                           'log',
                           '--pretty=format:%s%n%n%b',
                           previous + '..' + sha])

        review_request_id = None

        pos = message.find('Review:')
        if pos != -1:
            regex = 'Review: ({url})$'.format(
                url=urllib.parse.urljoin(reviewboard_url, 'r/[0-9]+'))
            pattern = re.compile(regex)
            match = pattern.search(message[pos:].strip().strip('/'))
            if match is None:
                print("\nInvalid ReviewBoard URL: '{}'".format(message[pos:]))
                sys.exit(1)

            url = match.group(1)
            review_request_id = url.split('/')[-1]

        # Show the commit.
        if review_request_id is None:
            output = check_output([
                'git',
                '--no-pager',
                'log',
                '--pretty=format:%Cred%H%Creset -%C(yellow)%d%Creset %s',
                previous + '..' + sha])
            print('\nCreating diff of:')
            sys.stdout.buffer.write(output)
        else:
            output = check_output([
                'git',
                '--no-pager',
                'log',
                '--pretty=format:%Cred%H%Creset -%C'
                '(yellow)%d%Creset %s %Cgreen(%cr)%Creset',
                previous + '..' + sha])
            print('\nUpdating diff of:')
            sys.stdout.buffer.write(output)

        # Show the "parent" commit(s).
        output = check_output([
            'git',
            '--no-pager',
            'log',
            '--pretty=format:%Cred%H%Creset -%C'
            '(yellow)%d%Creset %s %Cgreen(%cr)%Creset',
            tracking_branch + '..' + previous])

        if output:
            print('\n... with parent diff created from:')
            sys.stdout.buffer.write(output)

        try:
            input('\nPress enter to continue or \'Ctrl-C\' to skip.\n')
        except KeyboardInterrupt:
            i = i + 1
            previous = sha
            parent_review_request_id = review_request_id
            continue

        # Strip the review url from the commit message, so that
        # it is not included in the summary message when GUESS_FIELDS
        # is set in .reviewboardc. Update the SHA appropriately.
        if review_request_id:
            stripped_message = message[:pos]
            execute(['git', 'checkout', sha])
            execute(['git', 'commit', '--amend', '-m', stripped_message])
            sha = execute(['git', 'rev-parse', 'HEAD']).strip()
            execute(['git', 'checkout', branch])

        revision_range = previous + ':' + sha

        # Build the post-review/rbt command up
        # to the point where they are common.
        command = post_review

        if not args.no_markdown:
            command = command + ['--markdown']

        if args.bugs_closed:
            command = command + ['--bugs-closed=' + args.bugs_closed]

        if args.target_people:
            command = command + ['--target-people=' + args.target_people]

        if args.tracking_branch is None:
            command = command + ['--tracking-branch=' + tracking_branch]

        if review_request_id:
            command = command + ['--review-request-id=' + review_request_id]

        # Determine how to specify the revision range.
        if rbt_command in post_review and \
           rbt_version >= LooseVersion('RBTools 0.6'):
            # rbt >= 0.6.1 supports '--depends-on' argument.
            # Only set the "depends on" if this
            # is not  the first review in the chain.
            if rbt_version >= LooseVersion('RBTools 0.6.1') and \
               parent_review_request_id:
                command = command + ['--depends-on=' + parent_review_request_id]

            # rbt >= 0.6 revisions are passed in as args.
            command = command + sys.argv[1:] + [previous, sha]
        else:
            # post-review and rbt < 0.6 revisions are
            # passed in using the revision range option.
            command = command + \
                ['--revision-range=' + revision_range] + \
                sys.argv[1:]

        output = execute(command).strip()

        # Output is a string, we convert it to a byte string before writing it.
        sys.stdout.buffer.write(output.encode())

        # If we already have a request_id, continue on to the next commit in the
        # chain. We update 'previous' from the shas[] array because we have
        # overwritten the temporary sha variable above.
        if review_request_id is not None:
            previous = shas[i]
            parent_review_request_id = review_request_id
            i = i + 1
            continue

        # Otherwise, get the request_id from the output of post-review, append
        # it to the commit message and rebase all other commits on top of it.
        lines = output.split('\n')

        # The last line of output in post-review is the review url.
        # The second to the last line of output in rbt is the review url.
        url = lines[len(lines) - 2] if rbt_command in post_review \
            else lines[len(lines) - 1]

        # Using rbt >= 0.6.3 on Linux prints out two URLs where the second
        # one has /diff/ at the end. We want to remove this so that a
        # subsequent call to post-reviews does not fail when looking up
        # the reviewboard entry to edit.
        url = url.replace('diff/', '')
        url = url.strip('/')
        review_request_id = os.path.basename(url)

        # Construct new commit message.
        message = message + '\n' + 'Review: ' + url + '\n'

        execute(['git', 'checkout', '-b', temporary_branch])
        execute(['git', 'reset', '--hard', sha])
        execute(['git', 'commit', '--amend', '-m', message])

        # Now rebase all remaining shas on top of this amended commit.
        j = i + 1
        old_sha = execute(
            ['git', 'rev-parse', '--verify', temporary_branch]).strip()
        previous = old_sha
        while j < len(shas):
            execute(['git', 'checkout', shas[j]])
            execute(['git', 'rebase', temporary_branch])
            # Get the sha for our detached HEAD.
            new_sha = execute([
                'git',
                '--no-pager',
                'log',
                '--pretty=format:%H', '-n', '1', 'HEAD']).strip()
            execute(['git',
                     'update-ref',
                     'refs/heads/' + temporary_branch,
                     new_sha,
                     old_sha])
            old_sha = new_sha
            shas[j] = new_sha
            j = j + 1

        # Okay, now update the actual branch to our temporary branch.
        new_sha = old_sha
        old_sha = execute(['git', 'rev-parse', '--verify', branch]).strip()
        execute(['git', 'update-ref', 'refs/heads/' + branch, new_sha, old_sha])

        i = i + 1
        parent_review_request_id = review_request_id

if __name__ == '__main__':
    main()
