#!/usr/bin/env python
##
# 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.
#
# Makes a patch for the current branch, creates/updates the review board request and uploads new
# patch to jira. Patch is named as (JIRA).(branch name).(patch number).patch as per Yetus' naming
# rules. If no jira is specified, patch will be named (branch name).patch and jira and review board
# are not updated. Review board id is retrieved from the remote link in the jira.
# Print help: submit-patch.py --h
import argparse
import getpass
import git
import json
import logging
import os
import re
import requests
import subprocess
import sys

parser = argparse.ArgumentParser(
    epilog = "To avoid having to enter jira/review board username/password every time, setup an "
             "encrypted ~/.apache-cred files as follows:\n"
             "1) Create a file with following single "
             "line: \n{\"jira_username\" : \"appy\", \"jira_password\":\"123\", "
             "\"rb_username\":\"appy\", \"rb_password\" : \"@#$\"}\n"
             "2) Encrypt it with openssl.\n"
             "openssl enc -aes-256-cbc -in <file> -out ~/.apache-creds\n"
             "3) Delete original file.\n"
             "Now onwards, you'll need to enter this encryption key only once per run. If you "
             "forget the key, simply regenerate ~/.apache-cred file again.",
    formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument("-b", "--branch",
                    help = "Branch to use for generating diff. If not specified, tracking branch "
                         "is used. If there is no tracking branch, error will be thrown.")

# Arguments related to Jira.
parser.add_argument("-jid", "--jira-id",
                    help = "Jira id of the issue. If set, we deduce next patch version from "
                           "attachments in the jira and also upload the new patch. Script will "
                           "ask for jira username/password for authentication. If not set, "
                           "patch is named <branch>.patch.")

# Arguments related to Review Board.
parser.add_argument("-srb", "--skip-review-board",
                    help = "Don't create/update the review board.",
                    default = False, action = "store_true")
parser.add_argument("--reviewers",
                    help = "Comma separated list of users to add as reviewers.")

# Misc arguments
parser.add_argument("--patch-dir", default = "~/patches",
                    help = "Directory to store patch files. If it doesn't exist, it will be "
                          "created. Default: ~/patches")
parser.add_argument("--rb-repo", default = "hbase-git",
                    help = "Review board repository. Default: hbase-git")
args = parser.parse_args()

# Setup logger
logging.basicConfig()
logger = logging.getLogger("submit-patch")
logger.setLevel(logging.INFO)


def log_fatal_and_exit(*arg):
    logger.fatal(*arg)
    sys.exit(1)


def assert_status_code(response, expected_status_code, description):
    if response.status_code != expected_status_code:
        log_fatal_and_exit(" Oops, something went wrong when %s. \nResponse: %s %s\nExiting..",
                           description, response.status_code, response.reason)


# Make repo instance to interact with git repo.
try:
    repo = git.Repo(os.getcwd())
    git = repo.git
except git.exc.InvalidGitRepositoryError as e:
    log_fatal_and_exit(" '%s' is not valid git repo directory.\nRun from base directory of "
                       "HBase's git repo.", e)

logger.info(" Active branch: %s", repo.active_branch.name)
# Do not proceed if there are uncommitted changes.
if repo.is_dirty():
    log_fatal_and_exit(" Git status is dirty. Commit locally first.")


# Returns base branch for creating diff.
def get_base_branch():
    # if --branch is set, use it as base branch for computing diff. Also check that it's a valid branch.
    if args.branch is not None:
        base_branch = args.branch
        # Check that given branch exists.
        for ref in repo.refs:
            if ref.name == base_branch:
                return base_branch
        log_fatal_and_exit(" Branch '%s' does not exist in refs.", base_branch)
    else:
        # if --branch is not set, use tracking branch as base branch for computing diff.
        # If there is no tracking branch, log error and quit.
        tracking_branch = repo.active_branch.tracking_branch()
        if tracking_branch is None:
            log_fatal_and_exit(" Active branch doesn't have a tracking_branch. Please specify base "
                               " branch for computing diff using --branch flag.")
        logger.info(" Using tracking branch as base branch")
        return tracking_branch.name


# Returns patch name having format (JIRA).(branch name).(patch number).patch. If no jira is
# specified, patch is name (branch name).patch.
def get_patch_name(branch):
    if args.jira_id is None:
        return branch + ".patch"

    patch_name_prefix = args.jira_id.upper() + "." + branch
    return get_patch_name_with_version(patch_name_prefix)


# Fetches list of attachments from the jira, deduces next version for the patch and returns final
# patch name.
def get_patch_name_with_version(patch_name_prefix):
    # JIRA's rest api is broken wrt to attachments. https://jira.atlassian.com/browse/JRA-27637.
    # Using crude way to get list of attachments.
    url = "https://issues.apache.org/jira/browse/" + args.jira_id
    logger.info("Getting list of attachments for jira %s from %s", args.jira_id, url)
    html = requests.get(url)
    if html.status_code == 404:
        log_fatal_and_exit(" Invalid jira id : %s", args.jira_id)
    if html.status_code != 200:
        log_fatal_and_exit(" Cannot fetch jira information. Status code %s", html.status_code)
    # Iterate over patch names starting from version 1 and return when name is not already used.
    content = unicode(html.content, 'utf-8')
    for i in range(1, 1000):
        name = patch_name_prefix + "." + ('{0:03d}'.format(i)) + ".patch"
        if name not in content:
            return name


# Validates that patch directory exists, if not, creates it.
def validate_patch_dir(patch_dir):
    # Create patch_dir if it doesn't exist.
    if not os.path.exists(patch_dir):
        logger.warn(" Patch directory doesn't exist. Creating it.")
        os.mkdir(patch_dir)
    else:
        # If patch_dir exists, make sure it's a directory.
        if not os.path.isdir(patch_dir):
            log_fatal_and_exit(" '%s' exists but is not a directory. Specify another directory.",
                               patch_dir)


# Make sure current branch is ahead of base_branch by exactly 1 commit. Quits if
# - base_branch has commits not in current branch
# - current branch is same as base branch
# - current branch is ahead of base_branch by more than 1 commits
def check_diff_between_branches(base_branch):
    only_in_base_branch = git.log("HEAD.." + base_branch, oneline = True)
    only_in_active_branch = git.log(base_branch + "..HEAD", oneline = True)
    if len(only_in_base_branch) != 0:
        log_fatal_and_exit(" '%s' is ahead of current branch by %s commits. Rebase "
                           "and try again.", base_branch, len(only_in_base_branch.split("\n")))
    if len(only_in_active_branch) == 0:
        log_fatal_and_exit(" Current branch is same as '%s'. Exiting...", base_branch)
    if len(only_in_active_branch.split("\n")) > 1:
        log_fatal_and_exit(" Current branch is ahead of '%s' by %s commits. Squash into single "
                           "commit and try again.",
                           base_branch, len(only_in_active_branch.split("\n")))


# If ~/.apache-creds is present, load credentials from it otherwise prompt user.
def get_credentials():
    creds = dict()
    creds_filepath = os.path.expanduser("~/.apache-creds")
    if os.path.exists(creds_filepath):
        try:
            logger.info(" Reading ~/.apache-creds for Jira and ReviewBoard credentials")
            content = subprocess.check_output("openssl enc -aes-256-cbc -d -in " + creds_filepath,
                                              shell=True)
        except subprocess.CalledProcessError as e:
            log_fatal_and_exit(" Couldn't decrypt ~/.apache-creds file. Exiting..")
        creds = json.loads(content)
    else:
        creds['jira_username'] = raw_input("Jira username:")
        creds['jira_password'] = getpass.getpass("Jira password:")
        if not args.skip_review_board:
            creds['rb_username'] = raw_input("Review Board username:")
            creds['rb_password'] = getpass.getpass("Review Board password:")
    return creds


def attach_patch_to_jira(issue_url, patch_filepath, patch_filename, creds):
    # Upload patch to jira using REST API.
    headers = {'X-Atlassian-Token': 'no-check'}
    files = {'file': (patch_filename, open(patch_filepath, 'rb'), 'text/plain')}
    jira_auth = requests.auth.HTTPBasicAuth(creds['jira_username'], creds['jira_password'])
    attachment_url = issue_url + "/attachments"
    r = requests.post(attachment_url, headers = headers, files = files, auth = jira_auth)
    assert_status_code(r, 200, "uploading patch to jira")


def get_jira_summary(issue_url):
    r = requests.get(issue_url + "?fields=summary")
    assert_status_code(r, 200, "fetching jira summary")
    return json.loads(r.content)["fields"]["summary"]


def get_review_board_id_if_present(issue_url, rb_link_title):
    r = requests.get(issue_url + "/remotelink")
    assert_status_code(r, 200, "fetching remote links")
    links = json.loads(r.content)
    for link in links:
        if link["object"]["title"] == rb_link_title:
            res = re.search("reviews.apache.org/r/([0-9]+)", link["object"]["url"])
            return res.group(1)
    return None


base_branch = get_base_branch()
# Remove remote repo name from branch name if present. This assumes that we don't use '/' in
# actual branch names.
base_branch_without_remote = base_branch.split('/')[-1]
logger.info(" Base branch: %s", base_branch)

check_diff_between_branches(base_branch)

patch_dir = os.path.abspath(os.path.expanduser(args.patch_dir))
logger.info(" Patch directory: %s", patch_dir)
validate_patch_dir(patch_dir)

patch_filename = get_patch_name(base_branch_without_remote)
logger.info(" Patch name: %s", patch_filename)
patch_filepath = os.path.join(patch_dir, patch_filename)

diff = git.format_patch(base_branch, stdout = True)
with open(patch_filepath, "w") as f:
    f.write(diff.encode('utf8'))

if args.jira_id is not None:
    creds = get_credentials()
    issue_url = "https://issues.apache.org/jira/rest/api/2/issue/" + args.jira_id

    attach_patch_to_jira(issue_url, patch_filepath, patch_filename, creds)

    if not args.skip_review_board:
        rb_auth = requests.auth.HTTPBasicAuth(creds['rb_username'], creds['rb_password'])

        rb_link_title = "Review Board (" + base_branch_without_remote + ")"
        rb_id = get_review_board_id_if_present(issue_url, rb_link_title)

        # If no review board link found, create new review request and add its link to jira.
        if rb_id is None:
            reviews_url = "https://reviews.apache.org/api/review-requests/"
            data = {"repository" : "hbase-git"}
            r = requests.post(reviews_url, data = data, auth = rb_auth)
            assert_status_code(r, 201, "creating new review request")
            review_request = json.loads(r.content)["review_request"]
            absolute_url = review_request["absolute_url"]
            logger.info(" Created new review request: %s", absolute_url)

            # Use jira summary as review's summary too.
            summary = get_jira_summary(issue_url)
            # Use commit message as description.
            description = git.log("-1", pretty="%B")
            update_draft_data = {"bugs_closed" : [args.jira_id.upper()], "target_groups" : "hbase",
                                 "target_people" : args.reviewers, "summary" : summary,
                                 "description" : description }
            draft_url = review_request["links"]["draft"]["href"]
            r = requests.put(draft_url, data = update_draft_data, auth = rb_auth)
            assert_status_code(r, 200, "updating review draft")

            draft_request = json.loads(r.content)["draft"]
            diff_url = draft_request["links"]["draft_diffs"]["href"]
            files = {'path' : (patch_filename, open(patch_filepath, 'rb'))}
            r = requests.post(diff_url, files = files, auth = rb_auth)
            assert_status_code(r, 201, "uploading diff to review draft")

            r = requests.put(draft_url, data = {"public" : True}, auth = rb_auth)
            assert_status_code(r, 200, "publishing review request")

            # Add link to review board in the jira.
            remote_link = json.dumps({'object': {'url': absolute_url, 'title': rb_link_title}})
            jira_auth = requests.auth.HTTPBasicAuth(creds['jira_username'], creds['jira_password'])
            r = requests.post(issue_url + "/remotelink", data = remote_link, auth = jira_auth,
                              headers={'Content-Type':'application/json'})
        else:
            logger.info(" Updating existing review board: https://reviews.apache.org/r/%s", rb_id)
            draft_url = "https://reviews.apache.org/api/review-requests/" + rb_id + "/draft/"
            diff_url = draft_url + "diffs/"
            files = {'path' : (patch_filename, open(patch_filepath, 'rb'))}
            r = requests.post(diff_url, files = files, auth = rb_auth)
            assert_status_code(r, 201, "uploading diff to review draft")

            r = requests.put(draft_url, data = {"public" : True}, auth = rb_auth)
            assert_status_code(r, 200, "publishing review request")
