#!/bin/bash

set -e

ARGS=$@
PROG=$(basename $0)

# Use supervisord or not (default to not)
USE_SUPERVISOR=

# Workers using more than MAXMEM will be restarted
MAXMEM=

# Number of workers to run in parrallel
CONCURRENCY=

# Debug level of celery output
LEVEL=debug

usage() {
    cat << EOF
USAGE: $0 [--concurrency N] [--maxmem M] [--level L] [--keep-alive]

Start celery with the given number of workers. If --keep-alive is specified,
start celery by way of supervisord, after generating a supervisor configuration
file to monitor and start the celery workers.

OPTIONS:
  --keep-alive      Use supervisord to keep Celery alive
  --concurrency N   Number of Celery workers to execute in parrallel (default from pymacaron.resources)
  --maxmem M        Workers using more than M megabytes get restarted (default from pymacaron.resources)
  --level L         Debug level of Celery workers (default: $LEVEL)
  --help            This help

USAGE:
  # Start celery with 8 workers and debug level
  pymasync --concurrency 8 --level debug

EOF
}


parse_args() {
    while [ "$1" != "" ]; do
        case $1 in
            "--keep-alive")   USE_SUPERVISOR=1;;
            "--debug")        set -x;;
            "--concurrency")  shift; CONCURRENCY=$1;;
            "--maxmem")       shift; MAXMEM=$1;;
            "--level")        shift; LEVEL=$1;;
            "-h" | "--help")  usage; exit 0;;
            *)                usage; exit 0;;
        esac
        shift
    done

}

parse_args $ARGS

if [ -z "$CONCURRENCY" ]; then
    CONCURRENCY="$(python -c 'from pymacaron.resources import get_celery_worker_count; print(get_celery_worker_count())' | tail -n 1)"
    echo "Setting --concurrency to $CONCURRENCY"
fi

if [ -z "$MAXMEM" ]; then
    MAXMEM="$(python -c 'from pymacaron.resources import get_celery_worker_memory_limit; print(get_celery_worker_memory_limit())' | tail -n 1)"
    echo "Setting --maxmem to $MAXMEM"
fi

PATH_CELERY=$(which celery)
CMD="$PATH_CELERY worker -E -A pymacaron_async --concurrency=$CONCURRENCY --loglevel=$LEVEL --include pymacaron_async.loader --max-memory-per-child=$MAXMEM"

# See example at https://github.com/celery/celery/blob/master/extra/supervisord/celeryd.conf
# And about redirection to stdout: http://veithen.io/2015/01/08/supervisord-redirecting-stdout.html
# And about getting supervisord in daemon mode to redirect to the container's stdout: https://stackoverflow.com/questions/18683810/docker-supervisord-and-logging-how-to-consolidate-logs-in-docker-logs#:~:text=Supervisord%20Configuration&text=So%20you%20need%20to%20%22redirect,see%20when%20running%20your%20container.&text=To%20the%20supervisord%20program%20configuration%20block.&text=This%20will%20redirect%20php5%2Dfpm,supervisord%20stdout%20via%20supervisord%2Dstdout.
# And running with nodaemon=true to have supervisord's logs merge with those of gunicorn threads in container logs
echo "Generating supervisord.conf"
cat <<EOF > supervisord.conf
# Auto-generated by pymasync - DONT TOUCH!
[supervisord]
logfile=/var/log/supervisord.log
logfile_maxbytes=50MB
logfile_backups=5
loglevel=$LEVEL
nodaemon=true

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock

[program:celeryd]
command=$CMD
stdout_logfile=/var/log/celery-workers.log
stderr_logfile=/var/log/celery-workers.log
logfile=/var/log/celery-workers.log
logfile_maxbytes=50MB
logfile_backups=5
autostart=true
autorestart=true
startsecs=10
stopwaitsecs=600
stopasgroup=true
priority=1000

EOF

echo "=> Command to start Celery:"
cat supervisord.conf | grep command | sed -e "s/command=//"

if [ -z "$USE_SUPERVISOR" ]; then
    echo "=> Starting celery without supervisor"
    eval $CMD
else
    echo "=> Starting supervisord"
    supervisord
fi
