#!/bin/bash

source "$(dirname $0)/vars"

verify_db_name() {
    sanitize_name "$1" "database name"
    DB_NAME="$1"
}

pgsql_shell() {
    DB_USER="$1"
    DB_PASSWORD="$2"
    shift 2
    ensure_database_container_is_running
    docker run -i --rm \
            --link="$DB_CONTAINER":"$DB_CONTAINER_LINK" \
            -e PGUSER="$DB_USER" \
            -e PGPASSWORD="$(cat "$DB_PASSWORD")" \
            "$DB_IMAGE" \
        bash -c "psql -v ON_ERROR_STOP=1 --host=\"$DB_HOST\" --port=\"$DB_PORT\" $@"
}

pgsql_admin() {
    pgsql_shell "root" "$DB_ADMIN_PASSWORD" "--dbname=root" "$@"
}

case "$1" in
  postgresql:create)
    verify_db_name "$2"
    verify_max_args 2 "$@"
    
    pgsql_admin <<EOF
CREATE DATABASE "$DB_NAME";
EOF
    info "PostgreSQL database created: $DB_NAME"
    ;;

  postgresql:delete|postgresql:destroy)
    verify_db_name "$2"
    verify_max_args 2 "$@"

    pgsql_admin <<EOF
DROP DATABASE "$DB_NAME";
EOF
    rm -f $DB_APP_DATABASES*/$DB_NAME
    info "PostgreSQL database deleted: $DB_NAME"
    ;;

  postgresql:list)
    verify_app_name "$2"
    verify_max_args 2 "$@"

    DB_LINKS="$DB_APP_DATABASES$APP/"
    mkdir -p "$DB_LINKS"
    ls -1 "$DB_LINKS"
    ;;

  postgresql:info)
    verify_app_name "$2"
    verify_db_name "$3"
    verify_max_args 3 "$@"

    if ! db_info "$APP" "$DB_NAME"; then
        fail "$DB_NAME: database is not linked to $APP"
    fi

    echo
    cat <<EOF
echo "       Host: $DB_HOST"
echo "       Port: $DB_PORT"
echo "       User: $DB_USER"
echo "       Password: $DB_PASSWORD"
echo "       Database: $DB_DATABASE"
echo
echo "       DATABASE_URL=$DB_URL"
EOF
    echo
    ;;

  postgresql:link)
    verify_app_name "$2"
    verify_db_name "$3"
    verify_max_args 3 "$@"

    DB_APP_PASSWORD="$DB_APP_PASSWORDS$APP"
    if [[ ! -f "$DB_APP_PASSWORD" ]]; then
        DB_NEW_PASSWORD="$(generate_random_password)"
        pgsql_admin <<EOF
CREATE USER "$APP" WITH PASSWORD '$DB_NEW_PASSWORD';
EOF
        echo "$DB_NEW_PASSWORD" > "$DB_APP_PASSWORD"
    fi

    pgsql_admin <<EOF
GRANT ALL PRIVILEGES ON DATABASE "$DB_NAME" TO "$APP";
EOF
    mkdir -p "$DB_APP_DATABASES$APP"
    touch "$DB_APP_DATABASES$APP/$DB_NAME"
    redeploy_app "$APP"
    ;;

  postgresql:unlink)
    verify_app_name "$2"
    verify_db_name "$3"
    verify_max_args 3 "$@"

    pgsql_admin <<EOF
REVOKE ALL PRIVILEGES ON DATABASE "$DB_NAME" FROM "$APP";
EOF
    rm "$DB_APP_DATABASES$APP/$DB_NAME"
    redeploy_app "$APP"
    ;;

  postgresql:console)
    verify_app_name "$2"
    verify_db_name "$3"
    verify_max_args 3 "$@"

    if ! db_info "$APP" "$DB_NAME"; then
        fail "$DB_NAME: database is not linked to $APP"
    fi

    shift 2
    docker run -t -i --rm \
            --link="$DB_CONTAINER":"$DB_CONTAINER_LINK" \
            -e PGDATABASE="$DB_NAME" \
            -e PGUSER="$DB_USER" \
            -e PGPASSWORD="$DB_PASSWORD" \
            -e DB_PORT="$DB_PORT" \
            "$DB_IMAGE" \
        bash -c "psql --host=\"$DB_HOST\" --port=\"$DB_PORT\""
    ;;

  help)
    cat && cat<<EOF
    postgresql:create <db>         Create a PostgreSQL database
    postgresql:delete <db>         Delete specified PostgreSQL database
    postgresql:list <app>          List linked databases
    postgresql:link <app> <db>     Link database to app
    postgresql:unlink <app> <db>   Unlink database from app
    postgresql:info <app> <db>     Display application informations
    postgresql:console <app> <db>  Launch console for PostgreSQL container
EOF
    ;;

esac
