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

# A hook script to prepare the commit log message.
# Automatically Called by "git commit" (including git cherry-pick).
# The hook's purpose is to edit the commit
# message. If the hook fails with a non-zero status,
# the commit is aborted. Users are allowed to further edit commit message
# generated by this hook.

# git examples to invoke the hook:
#
# Cherry-pick (please use -x):
# git cherry-pick -e <hash> -x
#
# Hotfix:
# git commit ...

import sys
import re

# 0: Hotfix 1: cherry-pick
commit_type = 0
keywords = ["[LI-HOTFIX]", "[LI-CHERRY-PICK]"]

commit_msg_file = sys.argv[1]
commit_source = None
if (len(sys.argv) >= 3):
	commit_source = sys.argv[2]

SHORT_HASH_LEN = 8
Original_Description_Key = "ORIGINAL_DESCRIPTION"
LI_Description_Key = "LI_DESCRIPTION"
LI_Description_Value = [""]
Ticket_Key = "TICKET"
Exit_Criteria_Key = "EXIT_CRITERIA"
Exit_Criteria_Value = ["MANUAL [\"\"]"]
Exit_Criteria_Help = ["# EXIT_CRITERIA = <EXIT_CRITERIA> <PARAMETERS>\n", "# e.g., \n", \
					  "# when the specified hash(s) is presented in the history, this commit is no longer needed:\n# EXIT_CRITERIA = HASH [<hash1>, <hash2> ...] \n", \
					  "# When the specified tickets are closed and there are patches with these tickets in the title in the commit history, this commit is no longer needed:\n# EXIT_CRITERIA = TICKET [<ticket1>, <ticket2> ...]\n", \
					  "# The exit criteria for this commit requires manual investigation:\n# EXIT_CRITERIA = MANUAL [<description>]\n"]

def writeKeyValue(fh, key, value, multiline):
	fh.write(key + " = ")
	if (multiline):
		fh.write("\n")
	for line in value:
		fh.write(line)
	fh.write("\n")
	return

with open (commit_msg_file, "r") as fh:
	oldMsg = fh.readlines()

firstline = ""

if (len(oldMsg) > 0):
	firstline = oldMsg[0].lstrip()

# skip already formatted commits
for word in keywords:
	if (firstline.startswith(word)):
		sys.exit(0)

actual_msg = []
comment_msg = []
for line in oldMsg[1:]:
	if (line.startswith("#")):
		comment_msg.append(line)
	else:
		actual_msg.append(line)

for line in oldMsg:
	cherry_pick_hash = re.search(r"\(cherry picked from commit ([^)]+)\)", line)
	if (cherry_pick_hash is not None):
		break
ticket = ""
if (cherry_pick_hash is not None):
	hash = cherry_pick_hash.group(1)
	print ("hash:" + hash)

	commit_type = 1

	match_ticket = re.search(r"(KAFKA-\d+)", firstline, re.I)

	if (match_ticket is not None):
		ticket = match_ticket.group(1)
		print(ticket)

	if (len(hash) > SHORT_HASH_LEN):
		short_hash = hash[:SHORT_HASH_LEN]
	else:
		short_hash = hash
	title = keywords[commit_type] + " [" + short_hash + "] " + firstline
	Exit_Criteria_Value = "HASH [" + hash + "]"

else:
	if not firstline:
		firstline = "\n"
	title = keywords[commit_type] + " " + firstline

# populate formatted commit message
with open(commit_msg_file, 'w') as f:
	f.write(title)
	writeKeyValue(f, Ticket_Key, [ticket], False)

	if (commit_type == 0 and len(actual_msg) > 0):
		LI_Description_Value = actual_msg
	writeKeyValue(f, LI_Description_Key, LI_Description_Value, True)

	writeKeyValue(f, Exit_Criteria_Key, Exit_Criteria_Value, False)

	if commit_source is None:
		for line in Exit_Criteria_Help:
			f.write(line)

	# for cherry-pick, preserve the original commit message
	if (commit_type == 1):
		writeKeyValue(f, Original_Description_Key, actual_msg, True)

	for line in comment_msg:
		f.write(line)

sys.exit(0)








