#!/usr/bin/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.
##############################################################################

# This script is designed to create a cherry pick PR to a target branch
#
# Usage: python3 cherry_pick_pr.py
#
# To test locally:
#
# git clone git@github.com:apache/arrow-rs.git /tmp/arrow-rs
#
# pip3 install PyGithub
# ARROW_GITHUB_API_TOKEN=<..>
#     CHECKOUT_ROOT=<path>
#     CHERRY_PICK_SHA=<sha> python3 cherry-pick-pr.py
#
import os
import sys
import six
import subprocess

from pathlib import Path

TARGET_BRANCH = 'active_release'
TARGET_REPO = 'apache/arrow-rs'

p = Path(__file__)

# Use github workspace if specified
repo_root = os.environ.get("CHECKOUT_ROOT")
if repo_root is None:
    print("arrow-rs checkout must be supplied in CHECKOUT_ROOT environment")
    sys.exit(1)

print("Using checkout in {}".format(repo_root))

token = os.environ.get('ARROW_GITHUB_API_TOKEN', None)
if token is None:
    print("GITHUB token must be supplied in ARROW_GITHUB_API_TOKEN environmet")
    sys.exit(1)

new_sha = os.environ.get('CHERRY_PICK_SHA', None)
if new_sha is None:
    print("SHA to cherry pick must be supplied in CHERRY_PICK_SHA environment")
    sys.exit(1)


# from merge_pr.py from arrow repo
def run_cmd(cmd):
    if isinstance(cmd, six.string_types):
        cmd = cmd.split(' ')
    try:
        output = subprocess.check_output(cmd)
    except subprocess.CalledProcessError as e:
        # this avoids hiding the stdout / stderr of failed processes
        print('Command failed: %s' % cmd)
        print('With output:')
        print('--------------')
        print(e.output)
        print('--------------')
        raise e

    if isinstance(output, six.binary_type):
        output = output.decode('utf-8')

    return output


os.chdir(repo_root)
new_sha_short = run_cmd("git rev-parse --short {}".format(new_sha)).strip()
new_branch = 'cherry_pick_{}'.format(new_sha_short)


def make_cherry_pick():
    if os.environ.get('GITHUB_SHA', None) is not None:
        print("Running on github runner, setting email/username")
        run_cmd(['git', 'config', 'user.email', 'dev@arrow.apache.com'])
        run_cmd(['git', 'config', 'user.name', 'Arrow-RS Automation'])

    #
    # Create a new branch from active_release
    # and cherry pick to there.
    #

    print("Creating cherry pick from {} to {}".format(
        new_sha_short, new_branch
    ))

    # The following tortured dance is required due to how the github
    # actions/checkout works (it doesn't pull other branches and pulls
    # only one commit back)

    # pull 10 commits back so we can get the proper cherry pick
    # (probably only need 2 but 10 must be better, right?)
    run_cmd(['git', 'fetch', '--depth', '10', 'origin', 'master'])
    run_cmd(['git', 'fetch', 'origin', 'active_release'])
    run_cmd(['git', 'checkout', '-b', new_branch])
    run_cmd(['git', 'reset', '--hard', 'origin/active_release'])
    run_cmd(['git', 'cherry-pick', new_sha])
    run_cmd(['git', 'push', '-u', 'origin', new_branch])



def make_cherry_pick_pr():
    from github import Github
    g = Github(token)
    repo = g.get_repo(TARGET_REPO)

    release_cherry_pick_label = repo.get_label('release-cherry-pick')
    cherry_picked_label = repo.get_label('cherry-picked')

    # Default titles
    new_title = 'Cherry pick {} to active_release'.format(new_sha)
    new_commit_message = 'Automatic cherry-pick of {}\n'.format(new_sha)

    # try and get info from github api
    commit = repo.get_commit(new_sha)
    for orig_pull in commit.get_pulls():
        new_commit_message += '* Originally appeared in {}: {}\n'.format(
            orig_pull.html_url, orig_pull.title)
        new_title = 'Cherry pick {} to active_release'.format(orig_pull.title)
        orig_pull.add_to_labels(cherry_picked_label)

    pr = repo.create_pull(title=new_title,
                          body=new_commit_message,
                          base='refs/heads/active_release',
                          head='refs/heads/{}'.format(new_branch),
                          maintainer_can_modify=True,
                          )

    pr.add_to_labels(release_cherry_pick_label)

    print('Created PR {}'.format(pr.html_url))


make_cherry_pick()
make_cherry_pick_pr()
