#!/usr/bin/env bash
# ---------------------------------------
#
# CHANGELOG
# 1.0.12:
#  - Add variables: ANSWER_DOCKER_ARGS_*
# ---------------------------------------

ANSWER_CLI_VERSION=1.0.12
# Missing versions:
# 4eefa2d == 1.0.9
# 3546143 == 1.0.8
# 2d5afb8 == 1.0.7
# 488e388 == 1.0.6
# 0bd5fe6 == 1.0.5
# 9b13fa0 == 1.0.4
# b67581b == 1.0.3
# fb0001c == 1.0.2
# f9499aa == 1.0.1

case "$(uname -s)" in
Darwin)
    ANSWER_CLI_PLATFORM=Darwin
    ;;
Linux)
    ANSWER_CLI_PLATFORM=Linux
    ;;
CYGWIN*|MINGW*|MSYS*)
    ANSWER_CLI_PLATFORM=Windows
    ;;
*)
    ANSWER_CLI_PLATFORM=Unknown
    ;;
esac


ANSWER_IMAGE_DB=postgres
ANSWER_IMAGE_S3=minio/minio
ANSWER_IMAGE_CORE=bogonets/answer-core
ANSWER_IMAGE_API=bogonets/answer-api
ANSWER_IMAGE_WEB=bogonets/answer-web
ANSWER_IMAGE_TURN=osom8979/turnserver

ANSWER_NAME_PREFIX=answer-cli-
ANSWER_NAME_DB=${ANSWER_NAME_PREFIX}db
ANSWER_NAME_S3=${ANSWER_NAME_PREFIX}s3
ANSWER_NAME_CORE=${ANSWER_NAME_PREFIX}core
ANSWER_NAME_API=${ANSWER_NAME_PREFIX}api
ANSWER_NAME_WEB=${ANSWER_NAME_PREFIX}web
ANSWER_NAME_TURN=${ANSWER_NAME_PREFIX}turn

ANSWER_TAG_DB=10
ANSWER_TAG_S3=RELEASE.2020-04-15T19-42-18Z
ANSWER_TAG_CORE=latest
ANSWER_TAG_API=latest
ANSWER_TAG_WEB=latest
ANSWER_TAG_TURN=latest

ANSWER_DOCKER_ARGS_DB=
ANSWER_DOCKER_ARGS_S3=
ANSWER_DOCKER_ARGS_CORE=
ANSWER_DOCKER_ARGS_API=
ANSWER_DOCKER_ARGS_WEB=
ANSWER_DOCKER_ARGS_TURN=

AUTOMATIC_YES=0
DRY_RUN=0
VERBOSE=0
POSITIONAL_ARGUMENTS=()

## Configurations

ANSWER_DB_PORT=5432
ANSWER_DB_USER=bogo
ANSWER_DB_PASSWORD=6090

ANSWER_S3_PORT=9000
ANSWER_S3_ID=minio
ANSWER_S3_PW=minio123

ANSWER_CORE_NODE=default
ANSWER_CORE_BIND=0.0.0.0
ANSWER_CORE_PORT=20002
ANSWER_CORE_VERBOSE=0
ANSWER_CORE_SYNC=1

ANSWER_API_PORT=20001
ANSWER_API_DB_URL=localhost
ANSWER_API_S3_URL=localhost
ANSWER_API_CORE_URL=localhost

ANSWER_WEB_HOST=0.0.0.0
ANSWER_WEB_PORT=20000

ANSWER_TURN_PORT=3478

ENABLE_GPU=0
GPUS=all
ENABLE_HOST_NETWORK=1
DOCKER_LOGS_TAIL_NUMBER=10

# https://docs.docker.com/engine/reference/run/#restart-policies---restart
# no, on-failure[:max-retries], always, unless-stopped,
DOCKER_RESTART=always

DEFAULT_USER_CONFIG=$(cat << EOF
ANSWER_IMAGE_DB=postgres
ANSWER_IMAGE_S3=minio/minio
ANSWER_IMAGE_CORE=bogonets/answer-core
ANSWER_IMAGE_API=bogonets/answer-api
ANSWER_IMAGE_WEB=bogonets/answer-web
ANSWER_IMAGE_TURN=osom8979/turnserver

ANSWER_TAG_CORE=latest
ANSWER_TAG_API=latest
ANSWER_TAG_WEB=latest
ANSWER_TAG_TURN=latest

ANSWER_DOCKER_ARGS_DB=
ANSWER_DOCKER_ARGS_S3=
ANSWER_DOCKER_ARGS_CORE=
ANSWER_DOCKER_ARGS_API=
ANSWER_DOCKER_ARGS_WEB=
ANSWER_DOCKER_ARGS_TURN=

ANSWER_DB_PORT=5432
ANSWER_DB_USER=bogo
ANSWER_DB_PASSWORD=6090

ANSWER_S3_PORT=9000
ANSWER_S3_ID=minio
ANSWER_S3_PW=minio123

ANSWER_CORE_NODE=default
ANSWER_CORE_BIND=0.0.0.0
ANSWER_CORE_PORT=20002
ANSWER_CORE_VERBOSE=0
ANSWER_CORE_SYNC=1

ANSWER_API_PORT=20001
ANSWER_API_DB_URL=localhost
ANSWER_API_S3_URL=localhost
ANSWER_API_CORE_URL=localhost

ANSWER_WEB_HOST=0.0.0.0
ANSWER_WEB_PORT=20000

ANSWER_TURN_PORT=3478

ENABLE_GPU=1
GPUS=all
ENABLE_HOST_NETWORK=1
DOCKER_LOGS_TAIL_NUMBER=10
DOCKER_RESTART=always
EOF
)

ANSWER_USER_HOME=$HOME/.answer
ANSWER_USER_CONFIG=$ANSWER_USER_HOME/answer-cli.config
ANSWER_USER_S3_CONFIG=$ANSWER_USER_HOME/s3.config
ANSWER_USER_S3_DATA=$ANSWER_USER_HOME/s3.data
ANSWER_USER_CORE_STORAGE=$ANSWER_USER_HOME/core.storage

function make_directory
{
    local dir=$1
    if [[ ! -d "$dir" ]]; then
        mkdir -p "$dir"
    fi
}

function print_message
{
    echo "$@"
}

function print_information
{
    echo -e "\033[32m$@\033[0m"
}

function print_warning
{
    echo -e "\033[33m$@\033[0m"
}

function print_verbose
{
    if [[ $VERBOSE -ne 0 ]]; then
        echo -e "\033[34m$@\033[0m"
    fi
}

function print_error
{
    echo -e "\033[31m$@\033[0m" 1>&2
}

function check_code_or_exit
{
    local code=$?
    if [[ $code -ne 0 ]]; then
        print_error "An error has been detected: $code"
        exit $code
    fi
}

function print_version
{
    print_message "${ANSWER_CLI_VERSION}"
}

function print_usage
{
    print_message "Usage: $0 [options] {command} {?module}"
    print_message " "
    print_message "Available options are:"
    print_message "  -h, --help     Print this message."
    print_message "  -v, --version  Print script version."
    print_message "  -y, --yes      Automatic yes to prompts."
    print_message "  -l, --list     List of options."
    print_message "  -n, --dry-run  Don’t actually do anything, just show what would be done."
    print_message "  -v, --verbose  Be more verbose/talkative during the operation."
    print_message "  --             Stop handling options."
    print_message " "
    print_message "List of commands:"
    print_message "  images         List images"
    print_message "  logs           View output from containers"
    print_message "  ps             List containers"
    print_message "  pull           Pull service images"
    print_message "  restart        Restart services"
    print_message "  rm             Remove stopped containers"
    print_message "  start          Start services"
    print_message "  stop           Stop services"
    print_message "  run            Create new containers"
    print_message " "
    print_message "List of modules:"
    print_message "  db             Database"
    print_message "  s3             Storage Service"
    print_message "  core           Answer core"
    print_message "  api            Answer api"
    print_message "  web            Answer web"
    print_message "  turn           Turn server"
    print_message " "
}

function _print_variable
{
    eval "print_message - \$1=\${$1}"
}

function print_list
{
    _print_variable ANSWER_IMAGE_DB
    _print_variable ANSWER_IMAGE_S3
    _print_variable ANSWER_IMAGE_CORE
    _print_variable ANSWER_IMAGE_API
    _print_variable ANSWER_IMAGE_WEB
    _print_variable ANSWER_IMAGE_TURN

    _print_variable ANSWER_TAG_CORE
    _print_variable ANSWER_TAG_API
    _print_variable ANSWER_TAG_WEB
    _print_variable ANSWER_TAG_TURN

    _print_variable ANSWER_DOCKER_ARGS_DB
    _print_variable ANSWER_DOCKER_ARGS_S3
    _print_variable ANSWER_DOCKER_ARGS_CORE
    _print_variable ANSWER_DOCKER_ARGS_API
    _print_variable ANSWER_DOCKER_ARGS_WEB
    _print_variable ANSWER_DOCKER_ARGS_TURN

    _print_variable ANSWER_DB_PORT
    _print_variable ANSWER_DB_USER
    _print_variable ANSWER_DB_PASSWORD

    _print_variable ANSWER_S3_PORT
    _print_variable ANSWER_S3_ID
    _print_variable ANSWER_S3_PW

    _print_variable ANSWER_CORE_NODE
    _print_variable ANSWER_CORE_BIND
    _print_variable ANSWER_CORE_PORT
    _print_variable ANSWER_CORE_VERBOSE
    _print_variable ANSWER_CORE_SYNC

    _print_variable ANSWER_API_PORT
    _print_variable ANSWER_API_DB_URL
    _print_variable ANSWER_API_S3_URL
    _print_variable ANSWER_API_CORE_URL

    _print_variable ANSWER_WEB_HOST
    _print_variable ANSWER_WEB_PORT

    _print_variable ANSWER_TURN_PORT

    _print_variable ENABLE_GPU
    _print_variable GPUS
    _print_variable ENABLE_HOST_NETWORK
    _print_variable DOCKER_LOGS_TAIL_NUMBER
}

function _exec_docker
{
    if [[ $DRY_RUN -ne 0 ]]; then
        print_message docker "$@"
    else
        docker "$@"
    fi
}

function run_images
{
    local module=$1
    case ${module} in
    db)
        _exec_docker images $ANSWER_IMAGE_DB
        ;;
    s3)
        _exec_docker images $ANSWER_IMAGE_S3
        ;;
    core)
        _exec_docker images $ANSWER_IMAGE_CORE
        ;;
    api)
        _exec_docker images $ANSWER_IMAGE_API
        ;;
    web)
        _exec_docker images $ANSWER_IMAGE_WEB
        ;;
    turn)
        _exec_docker images $ANSWER_IMAGE_TURN
        ;;
    all)
        local _tmp=$(_exec_docker images)
        echo "$_tmp" | head -1
        echo "$_tmp" | grep "$ANSWER_IMAGE_DB"
        echo "$_tmp" | grep "$ANSWER_IMAGE_S3"
        echo "$_tmp" | grep "$ANSWER_IMAGE_CORE"
        echo "$_tmp" | grep "$ANSWER_IMAGE_API"
        echo "$_tmp" | grep "$ANSWER_IMAGE_WEB"
        echo "$_tmp" | grep "$ANSWER_IMAGE_TURN"
        ;;
    all)
        ;;
    *)
        print_error "Unknown module name: ${module}"
        exit 1
        ;;
    esac
}

function run_logs
{
    local module=$1
    case ${module} in
    db|s3|core|api|web|turn)
        container_name=${ANSWER_NAME_PREFIX}${module}
        ;;
    all)
        print_error "The 'all' module is not supported."
        exit 1
        ;;
    *)
        print_error "Unknown module name: ${module}"
        exit 1
        ;;
    esac

    _exec_docker logs --tail ${DOCKER_LOGS_TAIL_NUMBER} --follow ${container_name}
}

function run_ps
{
    local module=$1
    case ${module} in
    db|s3|core|api|web|turn)
        container_name=${ANSWER_NAME_PREFIX}${module}
        ;;
    all)
        container_name=${ANSWER_NAME_PREFIX}
        ;;
    *)
        print_error "Unknown module name: ${module}"
        exit 1
        ;;
    esac

    _exec_docker ps --filter name=${container_name} \
                    --format '{{.Names}}\t({{.ID}}): {{.CreatedAt}}, Status={{.Status}}, Ports={{.Ports}}'
}

function run_pull
{
    local module=$1
    case $module in
    db)
        _exec_docker pull $ANSWER_IMAGE_DB:$ANSWER_TAG_DB
        ;;
    s3)
        _exec_docker pull $ANSWER_IMAGE_S3:$ANSWER_TAG_S3
        ;;
    core)
        _exec_docker pull $ANSWER_IMAGE_CORE:$ANSWER_TAG_CORE
        ;;
    api)
        _exec_docker pull $ANSWER_IMAGE_API:$ANSWER_TAG_API
        ;;
    web)
        _exec_docker pull $ANSWER_IMAGE_WEB:$ANSWER_TAG_WEB
        ;;
    turn)
        _exec_docker pull $ANSWER_IMAGE_TURN:$ANSWER_TAG_TURN
        ;;
    all)
        _exec_docker pull $ANSWER_IMAGE_DB:$ANSWER_TAG_DB
        _exec_docker pull $ANSWER_IMAGE_S3:$ANSWER_TAG_S3
        _exec_docker pull $ANSWER_IMAGE_CORE:$ANSWER_TAG_CORE
        _exec_docker pull $ANSWER_IMAGE_API:$ANSWER_TAG_API
        _exec_docker pull $ANSWER_IMAGE_WEB:$ANSWER_TAG_WEB
        _exec_docker pull $ANSWER_IMAGE_TURN:$ANSWER_TAG_TURN
        ;;
    *)
        print_error "Unknown module name: ${module}"
        exit 1
        ;;
    esac
}

function _exec_docker_common
{
    local command=$1
    local module=$2

    case ${module} in
    db|s3|core|api|web|turn)
        _exec_docker ${command} ${ANSWER_NAME_PREFIX}${module}
        ;;
    all)
        _exec_docker ${command} $ANSWER_NAME_DB
        _exec_docker ${command} $ANSWER_NAME_S3
        _exec_docker ${command} $ANSWER_NAME_CORE
        _exec_docker ${command} $ANSWER_NAME_API
        _exec_docker ${command} $ANSWER_NAME_WEB
        _exec_docker ${command} $ANSWER_NAME_TURN
        ;;
    *)
        print_error "Unknown module name: ${module}"
        exit 1
        ;;
    esac
}

function run_restart
{
    _exec_docker_common restart $1
}

function run_rm
{
    _exec_docker_common rm $1
}

function run_start
{
    _exec_docker_common start $1
}

function run_stop
{
    _exec_docker_common stop $1
}

function _run_answer_cli_db
{
    local image=${ANSWER_IMAGE_DB}:${ANSWER_TAG_DB}
    local args="-d --name ${ANSWER_NAME_DB}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_DB_PORT}:5432"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} -e POSTGRES_USER=${ANSWER_DB_USER}"
    args="${args} -e POSTGRES_PASSWORD=${ANSWER_DB_PASSWORD}"
    args="${args} ${ANSWER_DOCKER_ARGS_DB}"
    args="${args} ${image}"

    _exec_docker run ${args}
}

function _run_answer_cli_s3
{
    local guest_data_dir=/data
    local image=${ANSWER_IMAGE_S3}:${ANSWER_TAG_S3}
    local args="-d --name ${ANSWER_NAME_S3}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_S3_PORT}:${ANSWER_S3_PORT}"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} -e MINIO_ACCESS_KEY=${ANSWER_S3_ID}"
    args="${args} -e MINIO_SECRET_KEY=${ANSWER_S3_PW}"
    args="${args} -v ${ANSWER_USER_S3_CONFIG}:/root/.minio"
    args="${args} -v ${ANSWER_USER_S3_DATA}:${guest_data_dir}"
    args="${args} ${ANSWER_DOCKER_ARGS_S3}"
    args="${args} ${image}"
    args="${args} server ${guest_data_dir}"

    _exec_docker run ${args}
}

function _run_answer_cli_core
{
    local image=${ANSWER_IMAGE_CORE}:${ANSWER_TAG_CORE}
    local args="-d --name ${ANSWER_NAME_CORE}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_CORE_PORT}:${ANSWER_CORE_PORT}"
    fi
    if [[ $ENABLE_GPU -ne 0 ]]; then
        args="${args} --gpus $GPUS"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} -v ${ANSWER_USER_CORE_STORAGE}:/usr/local/c2core/storage"
    args="${args} ${ANSWER_DOCKER_ARGS_CORE}"
    args="${args} ${image}"

    if [[ $ANSWER_CORE_VERBOSE -ne 0 ]]; then
        args="${args} -v"
    fi
    if [[ $ANSWER_CORE_SYNC -ne 0 ]]; then
        args="${args} -s"
    fi
    args="${args} node ${ANSWER_CORE_NODE} tcp://${ANSWER_CORE_BIND}:${ANSWER_CORE_PORT}"

    _exec_docker run ${args}
}

function _run_answer_cli_api
{
    local image=${ANSWER_IMAGE_API}:${ANSWER_TAG_API}
    local args="-d --name ${ANSWER_NAME_API}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_API_PORT}:${ANSWER_API_PORT}"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} -e CORE_URL=${ANSWER_API_CORE_URL}"
    args="${args} -e CORE_PORT=${ANSWER_CORE_PORT}"
    args="${args} -e DB_URL=${ANSWER_API_DB_URL}"
    args="${args} -e DB_PORT=${ANSWER_DB_PORT}"
    args="${args} -e DB_USER=${ANSWER_DB_USER}"
    args="${args} -e DB_PASSWORD=${ANSWER_DB_PASSWORD}"
    args="${args} -e MINIO_URL=${ANSWER_API_S3_URL}"
    args="${args} -e MINIO_PORT=${ANSWER_S3_PORT}"
    args="${args} -e MINIO_ACCESS_TOKEN=${ANSWER_S3_ID}"
    args="${args} -e MINIO_SECRET_TOKEN=${ANSWER_S3_PW}"
    args="${args} ${ANSWER_DOCKER_ARGS_API}"
    args="${args} ${image}"

    _exec_docker run ${args}
}

function _run_answer_cli_web
{
    local image=${ANSWER_IMAGE_WEB}:${ANSWER_TAG_WEB}
    local args="-d --name ${ANSWER_NAME_WEB}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_WEB_PORT}:${ANSWER_WEB_PORT}"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} ${ANSWER_DOCKER_ARGS_WEB}"
    args="${args} ${image}"
    args="${args} --host=${ANSWER_WEB_HOST}"
    args="${args} --port=${ANSWER_WEB_PORT}"
    args="${args} --no-browser"

    _exec_docker run ${args}
}

function _run_answer_cli_turn
{
    local image=${ANSWER_IMAGE_TURN}:${ANSWER_TAG_TURN}
    local args="-d --name ${ANSWER_NAME_TURN}"
    if [[ $ENABLE_HOST_NETWORK -ne 0 ]]; then
        args="${args} --network host"
    else
        args="${args} -p ${ANSWER_TURN_PORT}:${ANSWER_TURN_PORT}"
    fi

    if [[ $ANSWER_CLI_PLATFORM == Windows ]]; then
        args="${args} -e TZ=Asia/Seoul"
    elif [[ $ANSWER_CLI_PLATFORM == Linux ]]; then
        args="${args} -v /etc/localtime:/etc/localtime:ro"
    fi

    if [[ -n $DOCKER_RESTART ]]; then
        args="${args} --restart=$DOCKER_RESTART"
    fi

    args="${args} ${ANSWER_DOCKER_ARGS_TURN}"
    args="${args} ${image}"

    _exec_docker run ${args}
}

function run_run
{
    local module=$1
    case $module in
    db)
        _run_answer_cli_db
        ;;
    s3)
        _run_answer_cli_s3
        ;;
    core)
        _run_answer_cli_core
        ;;
    api)
        _run_answer_cli_api
        ;;
    web)
        _run_answer_cli_web
        ;;
    turn)
        _run_answer_cli_turn
        ;;
    all)
        _run_answer_cli_db
        _run_answer_cli_s3
        _run_answer_cli_core
        _run_answer_cli_api
        _run_answer_cli_web
        _run_answer_cli_turn
        ;;
    *)
        print_error "Unknown module: $module"
        exit 1
        ;;
    esac
}

## -----------
## ENTRY-POINT
## -----------

while [[ -n $1 ]]; do
    case $1 in
    -v|--version)
        print_version
        exit 0
        ;;
    -h|--help)
        print_usage
        exit 0
        ;;
    -l|--list)
        print_list
        exit 0
        ;;
    -y|--yes)
        AUTOMATIC_YES=1
        shift
        ;;
    -n|--dry-run)
        DRY_RUN=1
        shift
        ;;
    -v|--verbose)
        VERBOSE=1
        shift
        ;;
    --)
        shift
        break
        ;;
    *)
        POSITIONAL_ARGUMENTS+=("$1")
        shift
        ;;
    esac
done

make_directory "$ANSWER_USER_HOME"
make_directory "$ANSWER_USER_S3_DATA"
make_directory "$ANSWER_USER_CORE_STORAGE"

## answer-cli configuration:
if [[ ! -f "$ANSWER_USER_CONFIG" ]]; then
    print_verbose "Create new configuration: $ANSWER_USER_CONFIG"
    echo "$DEFAULT_USER_CONFIG" > "$ANSWER_USER_CONFIG"
fi
if [[ -f "$ANSWER_USER_CONFIG" ]]; then
    print_verbose "Load configuration: $ANSWER_USER_CONFIG"
    source $ANSWER_USER_CONFIG
fi

ARGS_COUNT=${#POSITIONAL_ARGUMENTS[@]}
COMMAND=${POSITIONAL_ARGUMENTS[0]}
MODULE=${POSITIONAL_ARGUMENTS[1]:-all}

case $MODULE in
sss|minio)
    MODULE=s3
    ;;
database|postgres|postgresql)
    MODULE=db
    ;;
esac

if [[ -z $COMMAND ]]; then
    print_error "Please enter a command."
    exit 1
fi
if [[ -z $(which docker) ]]; then
    print_error "The 'docker' command is not found."
    exit 1
fi

if [[ $ENABLE_GPU -ne 0 && -z $(which nvidia-smi) ]]; then
    print_warning "The 'nvidia-smi' command is not found. Disable GPU features."
    ENABLE_GPU=0
fi

print_verbose "- Selected command: $COMMAND"
print_verbose "- Selected module: $MODULE"

case $COMMAND in
image|images)
    run_images ${MODULE}
    ;;
log|logs)
    run_logs ${MODULE}
    ;;
ps)
    run_ps ${MODULE}
    ;;
pull)
    run_pull ${MODULE}
    ;;
restart)
    run_restart ${MODULE}
    ;;
rm)
    run_rm ${MODULE}
    ;;
start)
    run_start ${MODULE}
    ;;
stop)
    run_stop ${MODULE}
    ;;
up|run)
    run_run ${MODULE}
    ;;
*)
    print_error "Unknown command: ${COMMAND}"
    exit 1
    ;;
esac

