#!/bin/bash -e
#
#Copyright (C) 2017 avideo authors (see AUTHORS)
#
#    This file is part of AVideo.
#
#    AVideo is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    AVideo is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with AVideo.  If not, see <http://www.gnu.org/licenses/>.

function series_new {
	#Create a new series: takes 2 parameters. $1 is this directory's path, and $2 is the date marker.
	
	if [ -z $2 ]; then
		REL_DATE=`date '+%Y.%-m'`
	else
		echo "Using alternative month data..."
		REL_DATE=$2
	fi
	
	#Set Up Workspace, Aborting if This Month's Release Already Exists
	if [ ! -z "`git branch | grep ${REL_DATE}`" ]; then
		echo "This Month's Release Already Exists; Aborting."
		exit 3
	fi
	git checkout master
	#Create repository to test for fatal error
	git checkout -b $REL_DATE
	if [ $? != 0 ]; then
		echo "Branch-Creation Error Encountered; Aborting."
		exit 4
	fi
	TZ=UTC date +%s > InitDate.txt
	cd ../Clone
	tar -czf "$1"/youtube-dl.tar.gz --exclude '.git' --exclude '.github' youtube-dl/
	cd "$1"
	git add youtube-dl.tar.gz InitDate.txt
	echo "Committing changes..."
	git commit -S -m "INIT for repos $2."
}

function release_clean {
	#Clean up non-release junk: takes 1 optional parameter. $1 is the software name.
	rm -f temp.txt tmp-output
	rm -Rf "$1"/ youtube-dl/
}

function release_build {
	#Build a release from patches: takes 1 parameter. $1 is the software name.
	release_clean $1
	tar -xzf youtube-dl.tar.gz
	#Copy in patch files, and remove evil files
	cat Patches/ban.txt | while read DEL_FILE
	do
		rm -R youtube-dl/${DEL_FILE}
	done
	cp -R Patches/Files/* youtube-dl/
	#Add some important files
	mv youtube-dl/AUTHORS tempauth
	echo "Youtube-DL Contributors:" > youtube-dl/AUTHORS
	cat tempauth >> youtube-dl/AUTHORS; rm tempauth
	echo -e "\nAVideo Contributors:" >> youtube-dl/AUTHORS
	cat AUTHORS >> youtube-dl/AUTHORS
	#List files in temp.txt and filter out references to interpreters
	find youtube-dl -type f -print > temp.txt
	xargs -a temp.txt sed -i '/swfinterp/d; /jsinterp/d'
	#Set up Git and version info...
	cd youtube-dl/
	devscripts/version.sh > /dev/null
	cd ..
	#Apply code patches and rebrand
	./func.py youtube-dl/ $1
	mkdir $1/BINFILES/
	diff expected_output.txt tmp-output
}

function release_pub {
	#Publish a release: takes 1 required parameter, and 2 optional parameter. $1 is the software name, $2 is --test or -t if tests are to be run, and $3 is --merge or -m if changes are to be merged into the master branch.
		
	read -p "Is ChangeLog up to date? (y/n) " -n 1 REPLY2
	if [[ ! $REPLY2 =~ ^[Yy]$ ]]; then exit 9; fi
	
	release_build $1
	version=`./$1/devscripts/version.sh`
	./wiki.py --series-update $version --dlpage $1 --sites-update $1 || ./wiki.py --series-make $version --dlpage $1 --sites-update $1
	cd $1/
	
	echo "Testing..."
	if [ "$2" == --test ] || [ "$2" == -t ]; then
		echo "Press ^C if you haven't sent through TOR but want to..."
		sleep 5
		nosetests --verbose --with-coverage --cover-package=youtube_dl --cover-html test --stop || exit 1
	else
		echo "Skipping Tests..."
	fi

	SERIES_CURRENT=`echo $version | awk -F . ' { print $1"."$2 } '`
	echo "Building Release Packages..."
	make pub
	#Upload to PyPI
	gpg -ab dist/*.tar.gz
	twine upload dist/*
	#Done Upload
	mv BINFILES/ ../../
	echo "Publishing Files..."
	cd ..
	git add Patches/Files/ChangeLog
	git commit -S -m "Das new ChangeLog" || true
	if [ ${@: -1} == "--merge" ] || [ ${@: -1} == "-m" ]; then
		series_merge
		git push origin master
	fi
	git push origin $SERIES_CURRENT
	git checkout archive
	if [ -d $version ]; then
		echo "Error: $version already exists. Aborting."
		rm -R ../BINFILES
		git checkout `echo $version | awk -F . ' { print $1"."$2 } '`
	fi
	mv ../BINFILES $version
	
	#Update Repo Files
	cd repos
	cat ../../Wiki/versions.txt | while read lineam
	do
		if [ "$lineam" == "" ]; then
			continue
		fi
		IFS=$'\t' read tag vrs <<< "$lineam"
		tag=`echo $tag | tr -cd [:alpha:]- | tr [:upper:] [:lower:]`
		if [ $(expr length "$tag") == 0 ]; then
			continue
		fi
		mkdir -p ${tag:0:-1}
		cd ${tag:0:-1}
		echo "Origin: notabug.org" > Packages
		echo "Components: main" >> Packages
		echo "Description: avideo official repositories" >> Packages
		echo "Architectures: all" >> Packages
		echo "SignWith: yes" >> Packages
		apt-ftparchive packages ../../$vrs >> Packages
		cat Packages | gzip -9c > Packages.gz
		echo "Origin: notabug.org" > Release
		echo "Architectures: all" >> Release
		echo "Components: main" >> Release
		echo "Description: official avideo "`basename $0`" repository" >> Release
		echo "SignWith: yes" >> Release
		apt-ftparchive release . >> Release
		rm Packages
		gpg --clearsign -o InRelease Release
		gpg -ab -o Release.gpg Release
		git add Packages.gz Release.gpg InRelease Release
		cd ..
	done
	cd ..
	
	git add $version/
	git commit -S -m "Release $version"
	git push origin archive

	echo "Posting Publication Information..."
	git checkout $SERIES_CURRENT
	cp $1/README.md ../Wiki/"User Documentation.md"
	cd ../Wiki
	git add Downloads.md "Supported Sites.md" "User Documentation.md"
	git commit -S -m "Release $version"
	git push origin master
}

function series_dep {
	#Deprecate a series: takes 2 parameters. $1 is the series to deprecate, and $2 is the software name.
	#UNTESTED!!!
	echo -n "Are you SURE you want to PERMANENTLY delete series ${1}?"
	read -n 1 TEMPANS
	if [ "$TEMPANS" != y ]; then
		exit
	fi
	if (cd ../Wiki; [ ! -z "`git status --porcelain`" ]); then
		echo "Error: workspace is not clean. Please stash or commit changes before continuing."
		exit 4
	fi
	git checkout master
	git branch -D $1
	git push origin :$1

	echo "Posting Deprecation Information..."
	./wiki.py --series-dep $1 --dlpage $2
	cd ../Wiki
	git add DOWNLOADS.md
	git commit $SIGN_COMMIT -m "Release $version"
	git push origin master
}

function series_list {
	#List series: takes 0 parameters.
	git branch | sed '/r/d; s/\*/\ /g'
}

function series_merge {
	#Prepare a specific series branch for (non-destructive) merging into master: takes 0 parameters.
	SERIES_CURRENT=`git rev-parse --abbrev-ref HEAD | tail -1`
	git stash
	git checkout master
	git merge $SERIES_CURRENT || true
	echo "Giving you a bash shell to resolve any merge conflicts; type 'exit' when done."
	bash
	for rem_file in youtube-dl.tar.gz InitDate.txt Patches/Bug; do
		git rm -r $rem_file || true
	done
	git commit -S -m "Merging from ${SERIES_CURRENT}" || true
	git checkout $SERIES_CURRENT
}

function series_giveHelp {
	#Print the help: takes 1 parameter. $1 is the command used to invoke this script.
	echo "Usage: $0 command [date marker]"
	echo "Command is one of:"
	echo "  make-	make a new series."
	echo "  dep-	deprecate a series."
	echo "  clean-	remove temporary files."
	echo "  build-	build a release package."
	echo "	pub-	publish a release."
	echo "  list-	list all series."
	echo "  merge-	merge to master."
	echo "  help-	print this help message."
	echo "A date marker is required for dep, and can be used with make to change the series created; it is ignored elsewhere."
	echo "For pub, two optional parameters are available: use --sign to sign commits, followed by --test to run tests. Omit arguments as relevant."
	exit
}



REL_BIGPATH=`realpath "$0"`
REL_PATH=`dirname "${REL_BIGPATH}"`

if [ $# -eq 0 ]; then
	echo "Error: Insufficient Arguments."
	series_giveHelp "$0"
fi

REL_NAME=avideo
cd "${REL_PATH}"
if [ "$1" == dep ]; then
	if [ $# -lt 2 ]; then
		echo "Error: No Date Marker for 'dep'."
		series_giveHelp "$0"
	fi
	series_dep $2 $REL_NAME
	exit
fi
if [ "$1" == make ]; then
	series_new "$REL_PATH" $2
	exit
fi
if [ "$1" == list ]; then
	series_list
	exit
fi
if [ "$1" == clean ]; then
	release_clean $REL_NAME
	exit
fi
if [ "$1" == build ]; then
	release_build $REL_NAME
	exit
fi
if [ "$1" == pub ]; then
	release_pub $REL_NAME $2 $3
	exit
fi
if [ "$1" == merge ]; then
	series_merge
	exit
fi
echo "Error: Command Not Recognized."
series_giveHelp "$0"