#!/usr/bin/env bash

# exit on errors
set -e

# check if we're in DEBUG mode
DEBUG=$(sed <.env -ne 's/^DEBUG=//p')

# disallow certain commands when debug is false
function prod_error {
    if [ "$DEBUG" != "true" ]; then
        echo "This command is not safe to run in production environments"
        exit 1
    fi
}

# import our ENV variables
# catch exits and give a friendly error message
function showerr {
    echo "Failed to load configuration! You may need to update your .env and quote values with special characters in them."
}
trap showerr EXIT
source .env
trap - EXIT

if docker compose &> /dev/null ; then
	DOCKER_COMPOSE="docker compose"
else
	DOCKER_COMPOSE="docker-compose"
fi

function clean {
    $DOCKER_COMPOSE stop
    $DOCKER_COMPOSE rm -f
}

function runweb {
    $DOCKER_COMPOSE run --rm web "$@"
}

function execdb {
    $DOCKER_COMPOSE exec db $@
}

function execweb {
    $DOCKER_COMPOSE exec web "$@"
}

function initdb {
    runweb python manage.py initdb "$@"
}

function migrate {
    runweb python manage.py migrate "$@"
}

function admin_code {
    runweb python manage.py admin_code
}

function awscommand {
    # expose env vars
    export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
    export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    export AWS_DEFAULT_REGION=${AWS_S3_REGION_NAME}
    # first arg is mountpoint, second is the whole aws command
    docker run --rm -it -v $1\
        -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_DEFAULT_REGION\
        amazon/aws-cli $2
}



CMD=$1
if [ -n "$CMD" ]; then
    shift
fi

# show commands as they're executed
set -x

case "$CMD" in
    up)
        $DOCKER_COMPOSE up --build "$@"
        ;;
    down)
        $DOCKER_COMPOSE down
        ;;
    service_ports_web)
        prod_error
        $DOCKER_COMPOSE run --rm --service-ports web
        ;;
    initdb)
        initdb "$@"
        ;;
    resetdb)
        prod_error
        $DOCKER_COMPOSE rm -svf
        docker volume rm -f bookwyrm_media_volume bookwyrm_pgdata bookwyrm_redis_activity_data bookwyrm_redis_broker_data bookwyrm_static_volume
        $DOCKER_COMPOSE build
        migrate
        migrate django_celery_beat
        initdb
        runweb python manage.py compile_themes
        runweb python manage.py collectstatic --no-input
        admin_code
        ;;
    makemigrations)
        prod_error
        runweb python manage.py makemigrations "$@"
        ;;
    migrate)
        migrate "$@"
        ;;
    bash)
        runweb bash
        ;;
    shell)
        runweb python manage.py shell
        ;;
    dbshell)
        execdb psql -U ${POSTGRES_USER} ${POSTGRES_DB}
        ;;
    restart_celery)
        $DOCKER_COMPOSE restart celery_worker
        ;;
    pytest)
        prod_error
        runweb pytest --no-cov-on-fail "$@"
        ;;
    pytest_coverage_report)
        prod_error
        runweb pytest -n 3 --cov-report term-missing "$@"
        ;;
    compile_themes)
        runweb python manage.py compile_themes
        ;;
    collectstatic)
        runweb python manage.py collectstatic --no-input
        ;;
    makemessages)
        prod_error
        runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@
        ;;
    compilemessages)
        runweb django-admin compilemessages --ignore venv $@
        ;;
    update_locales)
        prod_error
        git fetch origin l10n_main:l10n_main
        git checkout l10n_main locale/ca_ES
        git checkout l10n_main locale/de_DE
        git checkout l10n_main locale/eo_UY
        git checkout l10n_main locale/es_ES
        git checkout l10n_main locale/eu_ES
        git checkout l10n_main locale/fi_FI
        git checkout l10n_main locale/fr_FR
        git checkout l10n_main locale/gl_ES
        git checkout l10n_main locale/ko_KR
        git checkout l10n_main locale/it_IT
        git checkout l10n_main locale/lt_LT
        git checkout l10n_main locale/nl_NL
        git checkout l10n_main locale/no_NO
        git checkout l10n_main locale/pl_PL
        git checkout l10n_main locale/pt_PT
        git checkout l10n_main locale/pt_BR
        git checkout l10n_main locale/ro_RO
        git checkout l10n_main locale/sv_SE
        git checkout l10n_main locale/uk_UA
        git checkout l10n_main locale/zh_Hans
        git checkout l10n_main locale/zh_Hant
        runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@
        runweb django-admin compilemessages --ignore venv
        ;;
    build)
        $DOCKER_COMPOSE build
        ;;
    clean)
        prod_error
        clean
        ;;
    black)
        prod_error
        $DOCKER_COMPOSE run --rm dev-tools black celerywyrm bookwyrm
        ;;
    pylint)
        prod_error
        # pylint depends on having the app dependencies in place, so we run it in the web container
        runweb pylint bookwyrm/
        ;;
    prettier)
        prod_error
        $DOCKER_COMPOSE run --rm dev-tools prettier --write bookwyrm/static/js/*.js
        ;;
    eslint)
        prod_error
        $DOCKER_COMPOSE run --rm dev-tools eslint bookwyrm/static --ext .js
        ;;
    stylelint)
        prod_error
        $DOCKER_COMPOSE run --rm dev-tools stylelint --fix bookwyrm/static/css \
            --config dev-tools/.stylelintrc.js --ignore-path dev-tools/.stylelintignore
        ;;
    formatters)
        prod_error
        runweb pylint bookwyrm/
        $DOCKER_COMPOSE run --rm dev-tools black celerywyrm bookwyrm
        $DOCKER_COMPOSE run --rm dev-tools prettier --write bookwyrm/static/js/*.js
        $DOCKER_COMPOSE run --rm dev-tools eslint bookwyrm/static --ext .js
        $DOCKER_COMPOSE run --rm dev-tools stylelint --fix bookwyrm/static/css \
            --config dev-tools/.stylelintrc.js --ignore-path dev-tools/.stylelintignore
        ;;
    mypy)
        prod_error
        runweb mypy celerywyrm bookwyrm
        ;;
    collectstatic_watch)
        prod_error
        npm run --prefix dev-tools watch:static
        ;;
    update)
        git pull
        $DOCKER_COMPOSE build
        # ./update.sh
        runweb python manage.py migrate
        runweb python manage.py compile_themes
        runweb python manage.py collectstatic --no-input
        $DOCKER_COMPOSE up -d
        $DOCKER_COMPOSE restart web
        $DOCKER_COMPOSE restart celery_worker
        ;;
    populate_streams)
        runweb python manage.py populate_streams "$@"
        ;;
    populate_lists_streams)
        runweb python manage.py populate_lists_streams $@
        ;;
    populate_suggestions)
        runweb python manage.py populate_suggestions
        ;;
    generate_thumbnails)
        runweb python manage.py generateimages
        ;;
    generate_preview_images)
        runweb python manage.py generate_preview_images "$@"
        ;;
    remove_remote_user_preview_images)
        runweb python manage.py remove_remote_user_preview_images
        ;;
    erase_deleted_user_data)
        runweb python manage.py erase_deleted_user_data "$@"
        ;;
    copy_media_to_s3)
        awscommand "bookwyrm_media_volume:/images"\
            "s3 cp /images s3://${AWS_STORAGE_BUCKET_NAME}/images\
            --endpoint-url ${AWS_S3_ENDPOINT_URL}\
            --recursive --acl public-read" "$@"
        ;;
    sync_media_to_s3)
        awscommand "bookwyrm_media_volume:/images"\
            "s3 sync /images s3://${AWS_STORAGE_BUCKET_NAME}/images\
            --endpoint-url ${AWS_S3_ENDPOINT_URL}\
            --acl public-read" "$@"
        ;;
    set_cors_to_s3)
        set +x
        config_file=$1
        if [ -z "$config_file" ]; then
            echo "This command requires a JSON file containing a CORS configuration as an argument"
            exit 1
        fi
        set -x
        awscommand "$(pwd):/bw"\
            "s3api put-bucket-cors\
            --bucket ${AWS_STORAGE_BUCKET_NAME}\
            --endpoint-url ${AWS_S3_ENDPOINT_URL}\
            --cors-configuration file:///bw/$config_file" "$@"
        ;;
    admin_code)
        admin_code
        ;;
    setup)
        migrate
        migrate django_celery_beat
        initdb
        runweb python manage.py compile_themes
        runweb python manage.py collectstatic --no-input
        admin_code
        ;;
    runweb)
        runweb "$@"
        ;;
    remove_2fa)
        runweb python manage.py remove_2fa "$@"
        ;;
    confirm_email)
        runweb python manage.py confirm_email "$@"
        ;;
    *)
        set +x # No need to echo echo
        echo "Unrecognised command. Try:"
        echo "    setup"
        echo "    up [container]"
        echo "    down"
        echo "    service_ports_web"
        echo "    initdb"
        echo "    resetdb"
        echo "    makemigrations [migration]"
        echo "    migrate [migration]"
        echo "    bash"
        echo "    shell"
        echo "    dbshell"
        echo "    restart_celery"
        echo "    pytest [path]"
        echo "    compile_themes"
        echo "    collectstatic"
        echo "    makemessages"
        echo "    compilemessages [locale]"
        echo "    update_locales"
        echo "    build"
        echo "    clean"
        echo "    black"
        echo "    prettier"
        echo "    eslint"
        echo "    stylelint"
        echo "    formatters"
        echo "    mypy"
        echo "    collectstatic_watch"
        echo "    populate_streams [--stream=<stream name>]"
        echo "    populate_lists_streams"
        echo "    populate_suggestions"
        echo "    generate_thumbnails"
        echo "    generate_preview_images [--all]"
        echo "    remove_remote_user_preview_images"
        echo "    copy_media_to_s3"
        echo "    sync_media_to_s3"
        echo "    set_cors_to_s3 [cors file]"
        echo "    runweb [command]"
        echo "    remove_2fa"
        echo "    confirm_email"
        ;;
esac