#!/bin/bash

cd "$(dirname "$(which "$0")")/.."

. lib/conflib

get_platform() {
    if [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" -o "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
        echo "windows"
    else
        echo "other"
    fi
}

if test -z "$RUNTIME_PLATFORM"; then
    export RUNTIME_PLATFORM="`get_platform`"
fi

docker_env () {
    export WWW_DATA_UID="`id -u`"
    export WWW_DATA_GID="`id -g`"
    test -f ".config.env" && . .config.env
    "$@"
}

docker_compose () {
    if [ "$RUNTIME_PLATFORM" == "windows" ]; then
        docker_env winpty docker compose "$@"
    else
        docker_env docker compose "$@"
    fi
}

docker_configure() {
    . scripts/configure
}

do_initialize_deploy() {
    lib/invoke node bash scripts/initialize-node "$@"
    lib/invoke deploy bash scripts/initialize-deploy "$@"
}

do_initialize_runtime() {
    lib/invoke runtime bash scripts/initialize-runtime "$@"
}

do_initialize() {
    do_initialize_deploy "$@"
    do_initialize_runtime "$@"
}

docker_initialize() {
    do_initialize debug
}

docker_prod_update() {
    do_initialize prod
}

docker_prepare_deploy() {
    do_initialize_deploy prod
}

docker_runtime_update() {
    do_initialize_runtime prod
}

docker_up() {
    docker_compose up --build -d
    echo "Running at port: ${APP_PORT:-80}"
}

docker_down() {
    docker_compose down
}

docker_kill() {
    docker_compose kill
}

docker_restart() {
    docker_down
    docker_up
}

parse_container_name() {
    echo "$1" | cut -d: -f 1
}

parse_user_name() {
    if echo "$1" | grep -q ':'; then
        echo "$1" | cut -d: -f 2
    else
        if [ "$1" = "db" ]; then
            echo "mysql"
        else
            echo "www-data"
        fi
    fi
}

parse_operation() {
    if echo "$1" | grep -q ':[^:]*:'; then
        operation="`echo "$1" | cut -d: -f 3`"
    else
        operation="exec"
    fi
    if [ "$operation" = "run" ]; then
	echo run
    else
	echo exec
    fi
}

docker_exec() {
    if [ "$#" = 0 ]; then
        arg_error "container name expected"
        exit 1
    fi
    container="`parse_container_name "$1"`"
    user="`parse_user_name "$1"`"
    operation="`parse_operation "$1"`"

    shift

    if [ "$container" = "" ]; then
        arg_error "container name expected"
        exit 1
    fi

    tflag=""
    test -t 0 || tflag="-T"

    if [ "$#" = 0 ]; then
        docker_compose $operation $tflag --user "$user" "$container" bash
    else
        docker_compose $operation $tflag --user "$user" "$container" "$@"
    fi
}

arg_error() {
    echo "$1" 1>&2
    echo "use: "$0 help" for more help" 1>&2
}

show_help() {
    echo "usage: $0 command [arguments]" 1>&2
    echo "possible commands:" 1>&2
    echo "    configure" 1>&2
    echo "        configure the runtime environment" 1>&2
    echo "    up" 1>&2
    echo "        start all docker containers" 1>&2
    echo "    down" 1>&2
    echo "        stop all docker containers" 1>&2
    echo "    initialize" 1>&2
    echo "        initialize the application" 1>&2
    echo "    prod-update" 1>&2
    echo "        make production update of the application" 1>&2
    echo "    prepare-deploy" 1>&2
    echo "        prepare pakage for deploy" 1>&2
    echo "    runtime-update" 1>&2
    echo "        make a runtime update of the app" 1>&2
    echo "    kill" 1>&2
    echo "        kill all docker containers" 1>&2
    echo "    restart" 1>&2
    echo "        restart all docker containers" 1>&2
    echo "    compose [docker-compose-arguments]" 1>&2
    echo "        manually run docker-compose with all environment variables properly set" 1>&2
    echo "    exec container [command [arg1 [arg2 ...]]" 1>&2
    echo "        run a command in a given docker container" 1>&2
    echo "    help" 1>&2
    echo "        show this help" 1>&2
}

if [ "$#" = 0 ]; then
    show_help
    exit 1
fi

cmd="$1"
shift

case "$cmd" in
config|configure)
    docker_configure "$@";;
up|start)
    docker_up "$@";;
down|stop)
    docker_down "$@";;
init|initialize)
    docker_initialize "$@";;
prod-update|production-update|update-prod|update-production)
    docker_prod_update "$@";;
prepare-deploy|deploy-prepare)
    docker_prepare_deploy "$@";;
runtime-update|update-runtime)
    docker_runtime_update "$@";;
kill)
    docker_kill "$@";;
restart)
    docker_restart "$@";;
compose|dc)
    docker_compose "$@";;
env)
    docker_env "$@";;
exec)
    docker_exec "$@";;
help)
    show_help "$@";;
*)
    echo "unknown command: $cmd" 1>&2
    echo "use: "$0 help" for more help" 1>&2
    exit 1;;
esac
