#!/bin/bash
# ci.sh: Helper script to automate deployment operations on CI/CD
# Copyright © 2022 Aravinth Manivannan <realaravinth@batsense.net>
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# 
# This program 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 Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

set -xEeuo  pipefail
#source $(pwd)/scripts/lib.sh

readonly SSH_ID_FILE=/tmp/ci-ssh-id
readonly SSH_REMOTE_NAME=origin-ssh
readonly PROJECT_ROOT=$(pwd)

match_arg() {
    if [ $1 == $2 ] || [ $1 == $3 ]
    then
        return 0
    else
        return 1
    fi
}

help() {
	cat << EOF
USAGE: ci.sh [SUBCOMMAND]
Helper script to automate deployment operations on CI/CD

Subcommands

  -c  --clean	cleanup secrets, SSH key and other runtime data
  -i  --init <SSH_PRIVATE_KEY>	initialize environment, write SSH private to file
  -d  --deploy <PAGES-SECRET> <TARGET BRANCH>	push branch to Gitea and call Pages server
  -h  --help	print this help menu
EOF
}

# $1: SSH private key
write_ssh(){
	truncate --size 0 $SSH_ID_FILE
	echo "$1" > $SSH_ID_FILE
	chmod 600 $SSH_ID_FILE
}

set_ssh_remote() {
	http_remote_url=$(git remote get-url origin)
	remote_hostname=$(echo $http_remote_url | cut -d '/' -f 3) 
	repository_owner=$(echo $http_remote_url | cut -d '/' -f 4)
	repository_name=$(echo $http_remote_url | cut -d '/' -f 5)
	ssh_remote="git@$remote_hostname:$repository_owner/$repository_name"
	ssh_remote="git@git.batsense.net:libre-solutions/website.git"
	git remote add $SSH_REMOTE_NAME $ssh_remote
}

clean() {
	if [ -f $SSH_ID_FILE ]
	then
		shred $SSH_ID_FILE
		rm $SSH_ID_FILE
	fi
}

# $1: branch name
# $2: directory containing build assets
# $3: Author in <author-name author@example.com> format
commit_files() {
	cd $PROJECT_ROOT
	original_branch=$(git branch --show-current)
	tmp_dir=$(mktemp -d)
	cp -r $2/* $tmp_dir

	if [[ -z $(git ls-remote --heads origin ${1}) ]]
	then
		echo "[*] Creating deployment branch $1"
		git checkout --orphan $1
	else
		echo "[*] Deployment branch $1 exists, pulling changes from remote"
		git fetch origin $1
		git switch $1 
	fi

	git rm -rf .
	/bin/rm -rf *
	cp -r $tmp_dir/* .
	git add --all
	if [ $(git status --porcelain | xargs | sed '/^$/d' | wc -l) -gt 0 ];
	then
		echo "[*] Repository has changed, committing changes"
		git commit \
			--author="$3" \
			--message="new deploy: $(date --iso-8601=seconds)"
	fi
	git checkout $original_branch
}

# $1: Pages API secret
# $2: Deployment target branch
deploy() {
	if (( "$#" < 2 ))
	then
		help
	else
		git -c core.sshCommand="/usr/bin/ssh -oStrictHostKeyChecking=no -i $SSH_ID_FILE"\
			push --force  $SSH_REMOTE_NAME $2
		curl -vv --location --request \
				POST "https://deploy.batsense.net/api/v1/update"\
				--header 'Content-Type: application/json' \
				--data-raw "{ \"secret\": \"$1\", \"branch\": \"$2\" }"
	fi
}

if (( "$#" < 1 ))
then
	help
	exit -1
fi


if match_arg $1 '-i' '--init'
then
	if (( "$#" < 2 ))
	then
		help
		exit -1
	fi
	set_ssh_remote
	write_ssh "$2"
elif match_arg $1 '-c' '--clean'
then
	clean
elif match_arg $1 '-cf' '--commit-files'
then
	if (( "$#" < 4 ))
	then
		help
		exit -1
	fi
    commit_files $2 $3 $4
elif match_arg $1 '-d' '--deploy'
then
	if (( "$#" < 3 ))
	then
		help
		exit -1
	fi
	deploy $2 $3
elif match_arg $1 '-h' '--help'
then
	help
else
	help
fi
