#!/usr/bin/env python3

import os, sys, zipfile
import argparse
import subprocess

#### ####
# This scripts updates LibraryVersions.k (see $LIBRARYVERSIONS_REL_PATH) based on the artifacts
# in Google Maven (see $GMAVEN_BASE_URL).  It will only numerically increment alpha or beta versions.
# It will NOT change stability suffixes and it will NOT increment the version of a RC
# or stable library.  These changes should be done manually and purposefully.
#### ####

LIBRARYVERSIONS_REL_PATH = 'buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt'
FRAMEWORKS_SUPPORT_FULL_PATH = os.path.abspath(os.path.join(os.getcwd(), '..'))
LIBRARYVERSIONS_FULL_PATH = os.path.join(FRAMEWORKS_SUPPORT_FULL_PATH, LIBRARYVERSIONS_REL_PATH)
GMAVEN_BASE_URL = 'https://dl.google.com/dl/android/maven2/androidx/'
summary_log = []
exclude_dirs = []

# Defines an artifact in terms of its Maven Coorindates: artifactId, groupId, version
class MavenCoordinates:
	def __init__(self, artifactId, version):
		self.artifactId = artifactId
		self.version = version
		self.groupId = self.get_groupId_from_artifactId(artifactId)
	def get_groupId_from_artifactId(self, artifactId):
		# By convention, androidx namespace is declared as:
		# androidx.${groupId}:${groupId}-${optionalArtifactIdSuffix}:${version}
		# So, artifactId == "${groupId}-${optionalArtifactIdSuffix}"
		return artifactId.split('-')[0]

def print_e(*args, **kwargs):
	print(*args, file=sys.stderr, **kwargs)

def should_update_artifact(commlineArgs, groupId, artifactId):
	# Tells whether to update the given artifact based on the command-line arguments
	should_update = False
	if (commlineArgs.groups) or (commlineArgs.artifacts):
		if (commlineArgs.groups) and (groupId in commlineArgs.groups):
			should_update = True
		if (commlineArgs.artifacts) and (artifactId in commlineArgs.artifacts):
			should_update = True
	else:
		should_update = True
	return should_update

def print_change_summary():
	print("\n ---  SUMMARY --- ")
	for change in summary_log:
		print(change)

def read_in_lines_from_file(file_path):
	if not os.path.exists(file_path):
		print_e("File path does not exist: %s" % file_path)
		exit(1)
	else:
		with open(file_path, 'r') as f:
			lv_lines = f.readlines()
		return lv_lines

def write_lines_to_file(file_path, lines):
	if not os.path.exists(file_path):
		print_e("File path does not exist: %s" % file_path)
		exit(1)
	# Open file for writing and update all lines
	with open(file_path, 'w') as f:
		f.writelines(lines)

def get_artifactId_from_LibraryVersions_line(line):
	artifactId = line.split('val')[1]
	artifactId = artifactId.split('=')[0]
	artifactId = artifactId.strip(' ')
	artifactId = artifactId.lower()
	artifactId = artifactId.replace('_', '-')
	return artifactId

def get_version_or_macro_from_LibraryVersions_line(line):
	## Sample input:	'val ACTIVITY = Version("1.0.0-alpha04")'
	## Sample output: 	'1.0.0-alpha04', True
	## Sample input:	'val ACTIVITY = FRAGMENT'
	## Sample output: 	'fragment', False
	is_resolved = False
	version = ""
	if 'Version(' in line and '\"' in line:
		is_resolved = True
		version = line.split('\"')[1]
	else:
		is_resolved = False
		version = line.split('=')[-1].strip(' \n').lower().replace('_','-')
	return version, is_resolved

def get_tot_artifact_list(lv_lines):
	resolved_artifact_list = []
	unresolved_versions_list = []
	for cur_line in lv_lines:
		# Skip any line that doesn't declare a version
		if 'val' not in cur_line: continue
		artifactId = get_artifactId_from_LibraryVersions_line(cur_line)
		version, is_resolved = get_version_or_macro_from_LibraryVersions_line(cur_line)
		artifact = MavenCoordinates(artifactId, version)
		if is_resolved:
			resolved_artifact_list.append(artifact)
		else:
			# Artifact version specification is a reference to another artifact's
			# version -> it needs to be resolved
			unresolved_versions_list.append(artifact)
	# Resolve variable references in unresolved_versions_list to complete resolved_artifact_list.
	# This is needed because version MACROs can be a copy another version MACRO.  For example:
	#    val ARCH_CORE = Version("2.0.0")
	#    val ARCH_CORE_TESTING = ARCH_CORE
	for unresolved_artifact in unresolved_versions_list:
		artifactId_to_copy = unresolved_artifact.version
		for resolved_artifact in resolved_artifact_list:
			if resolved_artifact.artifactId == artifactId_to_copy:
				unresolved_artifact.version = resolved_artifact.version
				break
		resolved_artifact_list.append(unresolved_artifact)
	return resolved_artifact_list

def does_exist_on_gmaven(groupId, artifactId, version):
	print("Checking GMaven for %s-%s..." % (artifactId, version), end = '')
	# URLS are of the format:
	# https://dl.google.com/dl/android/maven2/androidx/${groupId}/${artifactId}/${version}/${artifactId}-${version}.pom
	artifactUrl = GMAVEN_BASE_URL + groupId + '/' + artifactId + '/' + version + '/' + artifactId + '-' + version + '.pom'
	try:
		# Curl the url to see if artifact pom exists
		curl_output = subprocess.check_output('curl -s %s' % artifactUrl, shell=True)
	except subprocess.CalledProcessError:
		print_e('FAIL: Failed to curl url: ' %  artifactUrl)
		return None
	if '404' in curl_output.decode():
		print("version is good")
		return False
	else:
		print("version is OUT OF DATE")
		return True

def increment_alpha_beta_version(version):
	# Only increment alpha and beta versions.
	# rc and stable should never need to be incremented in the androidx-main branch
	# Suffix changes should be done manually.
	changed = False
	if 'alpha' in version or 'beta' in version:
		changed = True
		# Assure we don't violate a version naming policy
		if not version[-1:].isdigit():
			print_e("--- --- \n Version %s has violated version naming policy!  Please fix." % version)
			exit(1)
		if version[-2:].isdigit():
			new_version = int(version[-2:]) + 1
			formatted_version = "%02d" % (new_version,)
			return version[:-2] + formatted_version, changed
		else:
			# Account for single digit versions with no preceding 0 (the leading 0 will be added)
			new_version = int(version[-1:]) + 1
			formatted_version = "%02d" % (new_version,)
			return version[:-1] + formatted_version, changed
	else:
		return version, changed

def artifactId_to_kotlin_macro(artifactId):
	return artifactId.replace('-','_').upper()

def update_artifact_version(lv_lines, artifact):
	num_lines = len(lv_lines)
	for i in range(num_lines):
		cur_line = lv_lines[i]
		# Skip any line that doesn't declare a version
		if 'val' not in cur_line: continue
		artifactId = get_artifactId_from_LibraryVersions_line(cur_line)
		if artifactId == artifact.artifactId:
			new_version, ver_was_updated = increment_alpha_beta_version(artifact.version)
			if ver_was_updated:
				# Only modify line if the version was actually changed
				lv_lines[i] ="    val " + artifactId_to_kotlin_macro(artifactId) + " = Version(\"" + new_version + "\")\n"
				summary_log.append("Updated %s to FROM %s TO %s" % (artifactId.upper(), artifact.version, new_version))
				# Assert incremented version doesn't exist
				if does_exist_on_gmaven(artifact.groupId, artifact.artifactId, new_version):
					print_e("--- --- \n Incremented version of %s from %s to %s, but %s has already been published!\
					  This needs to be fixed manually." % (artifact.artifactId, artifact.version, new_version, new_version))
					exit(1)

def update_api():
	try:
		os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
		curl_output = subprocess.check_output('./gradlew updateApi', shell=True)
		os.chdir(os.path.dirname(os.path.abspath(__file__)))
	except subprocess.CalledProcessError:
		print_e('FAIL: Failed gradle task updateApi!')
		return None

def update_library_versions(args):
	# Open LibraryVersions.kt file for reading and get all lines
	libraryversions_lines = read_in_lines_from_file(LIBRARYVERSIONS_FULL_PATH)
	tot_artifact_list = get_tot_artifact_list(libraryversions_lines)
	# Loop through every library version and update the version, if necessary
	versions_changed = False
	for artifact in tot_artifact_list:
		if should_update_artifact(args, artifact.groupId, artifact.artifactId):
			print("Updating %s " % artifact.artifactId)
			if does_exist_on_gmaven(artifact.groupId, artifact.artifactId, artifact.version):
				update_artifact_version(libraryversions_lines, artifact)
				versions_changed = True
	if versions_changed:
		write_lines_to_file(LIBRARYVERSIONS_FULL_PATH, libraryversions_lines)
		update_api()
		summary_log.append("These changes have not been committed.  Please double check before uploading.")
	else:
		summary_log.append("No changes needed.  All versions are update to date :)")


if __name__ == '__main__':
	# cd into directory of script
	os.chdir(os.path.dirname(os.path.abspath(__file__)))

	# Set up input arguments
	parser = argparse.ArgumentParser(
		description=('This script increments versions in LibraryVersions.kt based on artifacts released to Google Maven.'))
	parser.add_argument(
		'--groups', metavar='groupId', nargs='+',
		help="""If specified, only increments the version for libraries whose groupId contains the listed text.
		For example, if you specify \"--groups paging slice lifecycle\", then this
		script will increment the version of each library with groupId beginning with \"androidx.paging\", \"androidx.slice\",
		or \"androidx.lifecycle\"""")
	parser.add_argument(
		'--artifacts', metavar='artifactId', nargs='+',
		help="""If specified, only increments the version for libraries whose artifactId contains the listed text.
		For example, if you specify \"--artifacts core slice-view lifecycle-common\", then this
		script will increment the version for specific artifacts \"androidx.core:core\", \"androidx.slice:slice-view\",
		and \"androidx.lifecycle:lifecycle-common\"""")
	args = parser.parse_args()
	update_library_versions(args)
	print_change_summary()

