#!/bin/bash

set -ex

export HOME=/tmp/hostea

function install() {
    export DEBIAN_FRONTEND=noninteractive
    apt-get -qq update && apt-get -qq install --quiet -y rsync git wget > /dev/null
    if ! test -f /usr/bin/yq ; then
	wget --quiet -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.25.2/yq_linux_amd64
	chmod +x /usr/bin/yq
    fi
    docker pull --quiet enoughcommunity/enough:latest
    eval "$(docker run --rm enoughcommunity/enough:latest install --no-tty)"
}

function setup_git() {
    echo "$DEPLOY" > /tmp/key && chmod 600 /tmp/key
    export GIT_SSH_COMMAND="ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i/tmp/key"
    local remote=$(echo $CI_REPO_LINK | sed -Ee 's|https://([^/]*)/|git@\1:|')
    git remote rm origin
    git remote add origin $remote
    git fetch
}

function totmp() {
    local domain=$1
    rm -fr $HOME/.enough
    mkdir -p $HOME/.enough/$domain
    rsync -a --delete --exclude=.git ./ $HOME/.enough/$domain/
    if test -f $HOME/.enough/$domain/infrastructure_key ; then
	chmod 600 $HOME/.enough/$domain/infrastructure_key
    fi
}

function fromtmp() {
    local domain=$1
    #
    # services.yml is excluded because it is modified by enough and
    # gitea-service-group: will be duplicated from other files, making it
    # more difficult to remove a Gitea instance
    #
    rsync --exclude=services.yml -av $HOME/.enough/$domain/ ./
}

function push() {
    local comment="$1"
    git add .
    if git diff --staged --exit-code >& /dev/null ; then
	echo No changes to push
	return 1
    else
	git config user.email contact@hostea.org
	git config user.name 'HosteaBot'
	git commit -m "Update from hostea.sh: $comment"
	git push -u origin master || exit 1
	return 0
    fi
}

function ensure_domain_exists() {
    if test -f inventory/group_vars/all/domain.yml && test -f inventory/hosts.yml ; then
	return 0
    fi
    if test -z "$ENOUGH" ; then
	echo "secret ENOUGH is missing, must be set to create a subdomain"
	exit 1
    fi
    totmp example.com
    #
    # The host is created now because its IP is needed to create the glue record
    #
    enough --domain example.com host create bind-host
    #
    # The domain is created and a DNS glue recorded created to delegate it to bind-host 
    #
    docker run -e ENOUGH_API_TOKEN=$ENOUGH -v $HOME/.enough:/root/.enough --rm enoughcommunity/enough:latest --debug --domain example.com create test subdomain enough.community
    fromtmp example.com
    #
    # The private-key.yml file points to the example.com file, update it
    #
    local domain=$(yq .domain < inventory/group_vars/all/domain.yml)
    ( echo ansible_ssh_private_key_file: /root/.enough/$domain/infrastructure_key ) > inventory/group_vars/all/private-key.yml
    push_and_exit $domain "bind-host was created"
}

function push_and_exit() {
    local domain=$1
    local comment="$2"
    if ! push "$comment" ; then
	echo "there should be something to push but nothing was found"
	exit 1
    fi
    # because the push will re-trigger the CI and run the script again, only this time with the domain set
    exit 0
}

function ensure_bind_host() {
    local domain=$1
    local stone=$HOME/.enough/$domain/bind-host-configured
    if ! test -f $stone ; then
	enough --domain $domain service create --host bind-host bind
	enough --domain $domain service create --host bind-host backup
	touch $stone
	fromtmp $domain
	push_and_exit $domain "DNS and backup were configured"
    fi
}

function update_hostea() {
    local domain=$(yq .domain < inventory/group_vars/all/domain.yml)
    totmp $domain
    ensure_bind_host $domain
    for script in hosts-scripts/*.sh ; do
	source $script
    done
    fromtmp $domain
    push "the fleet was updated" || true  # it is ok if nothing changed
}

install
setup_git
ensure_domain_exists
update_hostea
