#!/bin/bash

set -eu -o pipefail

readonly curl="curl --fail --connect-timeout 20 --retry 10 --retry-delay 2 --max-time 2400"

function get_status() {
    key="$1"
    if status=$($curl -q -f "http://localhost:3000/api/v1/cloudron/status" 2>/dev/null); then
        currentValue=$(echo "${status}" | python3 -c 'import sys, json; print(json.dumps(json.load(sys.stdin)[sys.argv[1]]))' "${key}")
        echo "${currentValue}"
        return 0
    fi

    return 1
}

function wait_for_status() {
    key="$1"
    expectedValue="$2"

    echo "wait_for_status: $key to be $expectedValue"
    while true; do
        if currentValue=$(get_status "${key}"); then
            echo "wait_for_status: $key is current: $currentValue expecting: $expectedValue"
            if [[ "${currentValue}" == $expectedValue ]]; then
                break
            fi
        fi
        sleep 3
    done
}

domain=""
domainProvider=""
domainConfigJson="{}"
domainTlsProvider="letsencrypt-prod"
adminUsername="superadmin"
adminPassword="Secret123#"
adminEmail="admin@server.local"
appstoreUserId=""
appstoreToken=""
backupDir="/var/backups"

args=$(getopt -o "" -l "domain:,domain-provider:,domain-tls-provider:,admin-username:,admin-password:,admin-email:,appstore-user:,appstore-token:,backup-dir:" -n "$0" -- "$@")
eval set -- "${args}"

while true; do
    case "$1" in
    --domain) domain="$2"; shift 2;;
    --domain-provider) domainProvider="$2"; shift 2;;
    --domain-tls-provider) domainTlsProvider="$2"; shift 2;;
    --admin-username) adminUsername="$2"; shift 2;;
    --admin-password) adminPassword="$2"; shift 2;;
    --admin-email) adminEmail="$2"; shift 2;;
    --appstore-user) appstoreUser="$2"; shift 2;;
    --appstore-token) appstoreToken="$2"; shift 2;;
    --backup-dir) backupDir="$2"; shift 2;;
    --) break;;
    *) echo "Unknown option $1"; exit 1;;
    esac
done

echo "=> Waiting for cloudron to be ready"
wait_for_status "version" '*'

if [[ $(get_status "webadminStatus") != *'"tls": true'* ]]; then
    echo "=> Domain setup"
    dnsSetupData=$(printf '{ "domain": "%s", "adminFqdn": "%s", "provider": "%s", "config": %s, "tlsConfig": { "provider": "%s" } }' "${domain}" "my.${domain}" "${domainProvider}" "$domainConfigJson" "${domainTlsProvider}")

    if ! $curl -X POST -H "Content-Type: application/json" -d "${dnsSetupData}" http://localhost:3000/api/v1/cloudron/dns_setup; then
        echo "DNS Setup Failed"
        exit 1
    fi

    wait_for_status "webadminStatus" '*"tls": true*'
else
    echo "=> Skipping Domain setup"
fi

activationData=$(printf '{"username": "%s", "password":"%s", "email": "%s" }' "${adminUsername}" "${adminPassword}" "${adminEmail}")
if [[ $(get_status "activated") == "false" ]]; then
    echo "=> Activating"

    if ! activationResult=$($curl -X POST -H "Content-Type: application/json" -d "${activationData}" http://localhost:3000/api/v1/cloudron/activate); then
        echo "Failed to activate with ${activationData}: ${activationResult}"
        exit 1
    fi

    wait_for_status "activated" "true"
else
    echo "=> Skipping Activation"
fi

echo "=> Getting token"
if ! activationResult=$($curl -X POST -H "Content-Type: application/json" -d "${activationData}" http://localhost:3000/api/v1/developer/login); then
    echo "Failed to login with ${activationData}: ${activationResult}"
    exit 1
fi

accessToken=$(echo "${activationResult}" | python3 -c 'import sys, json; print(json.load(sys.stdin)[sys.argv[1]])' "accessToken")

echo "=> Setting up App Store account with accessToken ${accessToken}"
appstoreData=$(printf '{"userId":"%s", "token":"%s" }' "${appstoreUser}" "${appstoreToken}")

if ! appstoreResult=$($curl -X POST -H "Content-Type: application/json" -d "${appstoreData}" "http://localhost:3000/api/v1/settings/appstore_config?access_token=${accessToken}"); then
    echo "Failed to setup Appstore account with ${appstoreData}: ${appstoreResult}"
    exit 1
fi

echo "=> Setting up Backup Directory with accessToken ${accessToken}"
backupData=$(printf '{"provider":"filesystem", "key":"", "backupFolder":"%s", "retentionSecs": 864000, "format": "tgz", "externalDisk": true}' "${backupDir}")

chown -R yellowtent:yellowtent "${backupDir}"

if ! backupResult=$($curl -X POST -H "Content-Type: application/json" -d "${backupData}" "http://localhost:3000/api/v1/settings/backup_config?access_token=${accessToken}"); then
    echo "Failed to setup backup configuration with ${backupDir}: ${backupResult}"
    exit 1
fi

echo "=> Done!"

