#!/bin/bash

set -eu

mkdir -p /app/data/storage /run/peertube/cache /run/peertube/npm /tmp/peertube

# do not rely on WORKDIR
cd /app/code/server

migrate_ldap_to_oidc() {
    USERS_TO_MIGRATE=$(PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -AXqtc "SELECT count(*) FROM \"user\" u WHERE \"pluginAuth\"='peertube-plugin-auth-ldap'")
    echo "==> Migrating users to OIDC";
    echo "      Users to migrate: ${USERS_TO_MIGRATE}"
    if [ ${USERS_TO_MIGRATE} -gt 0 ]; then
        PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -c "UPDATE \"user\" SET \"pluginAuth\"='peertube-plugin-auth-openid-connect' WHERE \"pluginAuth\"='peertube-plugin-auth-ldap'"
    fi

    LDAP_PLUGIN_INSTALLED=$(PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -AXqtc "SELECT count(*) FROM \"plugin\" WHERE name='auth-ldap'")
    if [ ${LDAP_PLUGIN_INSTALLED} -gt 0 ]; then
        echo "==> Uninstalling LDAP plugin"
        gosu cloudron:cloudron npm run plugin:uninstall -- -n peertube-plugin-auth-ldap

        echo "==> Deleting LDAP settings"
        PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -c "DELETE FROM \"plugin\" WHERE name='auth-ldap'"
    fi
}

install_oidc() {
    # https://docs.joinpeertube.org/maintain-tools?id=cli-wrapper . Note that we have to restart peertube when installed this way
    if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
        echo "==> Installing OIDC plugin"
        gosu cloudron:cloudron npm run plugin:install -- -n peertube-plugin-auth-openid-connect -v 0.1.1
        update_oidc
    fi
}

update_oidc() {
    echo "==> Updating OIDC config"

    PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} \
        -c "UPDATE plugin SET settings='{\"scope\": \"openid email profile\", \"client-id\": \"${CLOUDRON_OIDC_CLIENT_ID}\", \"discover-url\": \"${CLOUDRON_OIDC_DISCOVERY_URL}\", \"client-secret\": \"${CLOUDRON_OIDC_CLIENT_SECRET}\", \"mail-property\": \"email\", \"auth-display-name\": \"Cloudron\", \"username-property\": \"preferred_username\", \"signature-algorithm\": \"RS256\", \"display-name-property\": \"name\"}' WHERE name='auth-openid-connect'"
}

first_time_setup() {
    echo "==> Starting peertube to run migrations on first run"
    gosu cloudron:cloudron npm start &  # be wary of https://stackoverflow.com/questions/70738567/why-does-running-npm-run-script-as-root-switch-user
    sleep 10

    while ! curl --silent --output /dev/null --fail http://localhost:9000/; do
        echo "==> Waiting for peertube"
        sleep 5
    done

    killall -SIGTERM peertube # this kills the process group
    sleep 5

    echo "==> Reset root password"
    echo "changeme" | gosu cloudron:cloudron npm run reset-password -- -u root
    sleep 5  # the above command seems to spawn a separate process to change password in background

    install_oidc

    echo "==> First time setup complete"
}

update_config() {
    echo "==> Ensure and updating configs"

    # version 5 needs this now
    if [[ `yq eval '.secrets | has("peertube")' /app/data/production.yaml` != "true" ]]; then
        yq eval ".secrets.peertube = \"`openssl rand -hex 32`\"" -i /app/data/production.yaml
    fi

    yq eval ".webserver.hostname = \"${CLOUDRON_APP_DOMAIN}\"" -i /app/data/production.yaml

    # database
    yq eval ".database.hostname = \"${CLOUDRON_POSTGRESQL_HOST}\"" -i /app/data/production.yaml
    yq eval ".database.port = ${CLOUDRON_POSTGRESQL_PORT}" -i /app/data/production.yaml
    yq eval ".database.username = \"${CLOUDRON_POSTGRESQL_USERNAME}\"" -i /app/data/production.yaml
    yq eval ".database.password = \"${CLOUDRON_POSTGRESQL_PASSWORD}\"" -i /app/data/production.yaml
    yq eval ".database.name = \"${CLOUDRON_POSTGRESQL_DATABASE}\"" -i /app/data/production.yaml
    yq eval "del(.database.suffix)" -i /app/data/production.yaml

    # redis
    yq eval ".redis.hostname = \"${CLOUDRON_REDIS_HOST}\"" -i /app/data/production.yaml
    yq eval ".redis.port = ${CLOUDRON_REDIS_PORT}" -i /app/data/production.yaml
    yq eval ".redis.auth = \"${CLOUDRON_REDIS_PASSWORD}\"" -i /app/data/production.yaml

    # smtp
    yq eval ".smtp.hostname = \"${CLOUDRON_MAIL_SMTP_SERVER}\"" -i /app/data/production.yaml
    yq eval ".smtp.port = ${CLOUDRON_MAIL_SMTP_PORT}" -i /app/data/production.yaml
    yq eval ".smtp.username = \"${CLOUDRON_MAIL_SMTP_USERNAME}\"" -i /app/data/production.yaml
    yq eval ".smtp.password = \"${CLOUDRON_MAIL_SMTP_PASSWORD}\"" -i /app/data/production.yaml
    yq eval ".smtp.tls = false" -i /app/data/production.yaml
    yq eval ".smtp.disable_starttls = true" -i /app/data/production.yaml
    yq eval ".smtp.from_address = \"${CLOUDRON_MAIL_FROM}\"" -i /app/data/production.yaml

    # ensure settings which were later added
    yq eval ".storage.bin = \"/app/data/storage/bin/\"" -i /app/data/production.yaml
    yq eval ".storage.well_known = \"/app/data/storage/well_known/\"" -i /app/data/production.yaml
    yq eval ".storage.tmp_persistent = \"/app/data/storage/tmp_persistent/\"" -i /app/data/production.yaml

    # changes for 6.0.0
    yq eval ".storage.storyboards = \"/app/data/storage/storyboards/\"" -i /app/data/production.yaml
    if [[ -d "/app/data/storage/videos" ]]; then
        echo "==> Migrate videos/ to videos-web/"
        mv /app/data/storage/videos /app/data/storage/web-videos
    fi
    yq eval ".storage.web_videos = \"/app/data/storage/web-videos/\"" -i /app/data/production.yaml
    yq eval "del(.storage.videos)" -i /app/data/production.yaml
    yq eval "del(.transcoding.webtorrent)" -i /app/data/production.yaml
    yq eval ".transcoding.web_videos.enabled = true" -i /app/data/production.yaml
}

echo "==> Changing ownership"
chown -R cloudron:cloudron /app/data /run/peertube /tmp/peertube

# Set eviction policy to prevent warnings - https://docs.bullmq.io/guide/going-to-production#max-memory-policy
while ! REDISCLI_AUTH="${CLOUDRON_REDIS_PASSWORD}" redis-cli -h "${CLOUDRON_REDIS_HOST}" -p "${CLOUDRON_REDIS_PORT}" ping >/dev/null; do
    echo "==> Waiting for redis"
    sleep 5
done
REDISCLI_AUTH="${CLOUDRON_REDIS_PASSWORD}"  redis-cli -h "${CLOUDRON_REDIS_HOST}" -p "${CLOUDRON_REDIS_PORT}" CONFIG SET maxmemory-policy noeviction

# cd /var/www/peertube/peertube-latest/scripts && sudo -H -u peertube ./upgrade.sh
if [[ ! -f "/app/data/production.yaml" ]]; then
    echo "==> First run. creating config"
    cp /app/pkg/production.yaml.example /app/data/production.yaml

    update_config
    first_time_setup
else
    update_config
    if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
        install_oidc
        migrate_ldap_to_oidc
        update_oidc
    fi
fi

echo "==> Configuring nginx"
cp /app/pkg/peertube-nginx.conf /run/peertube-nginx.conf

echo "==> Starting PeerTube"
#exec gosu cloudron:cloudron npm start
exec /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf --nodaemon -i PeerTube
