#!/usr/bin/env bash
[[ " build release trace delete ls run url urls version help " == *" $1 "* ]] || exit $DOKKU_NOT_IMPLEMENTED_EXIT
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"

case "$1" in
  build)
    APP="$2"; IMAGE_SOURCE_TYPE="$3"; TMP_WORK_DIR="$4"; IMAGE=$(get_app_image_name $APP)
    verify_app_name "$APP"

    CACHE_DIR="$DOKKU_ROOT/$APP/cache"

    eval "$(config_export app $APP)"
    pushd "$TMP_WORK_DIR" &> /dev/null

    case "$IMAGE_SOURCE_TYPE" in
      herokuish)
        id=$(tar -c . | docker run -i -a stdin $DOKKU_IMAGE /bin/bash -c "mkdir -p /app && tar -xC /app")
        test "$(docker wait $id)" -eq 0
        docker commit $id $IMAGE > /dev/null
        [[ -d $CACHE_DIR ]] || mkdir $CACHE_DIR
        plugn trigger pre-build-buildpack "$APP"

        DOCKER_ARGS=$(: | plugn trigger docker-args-build $APP $IMAGE_SOURCE_TYPE)
        [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
        id=$(docker run -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build)
        docker attach $id
        test "$(docker wait $id)" -eq 0
        docker commit $id $IMAGE > /dev/null

        plugn trigger post-build-buildpack "$APP"
        ;;

      dockerfile)
        # extract first port from Dockerfile
        DOCKERFILE_PORT=$(get_dockerfile_exposed_port Dockerfile)
        [[ -n "$DOCKERFILE_PORT" ]] && config_set --no-restart $APP DOKKU_DOCKERFILE_PORT=$DOCKERFILE_PORT
        plugn trigger pre-build-dockerfile "$APP"

        [[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
        DOCKER_ARGS=$(: | plugn trigger docker-args-build $APP $IMAGE_SOURCE_TYPE)
        docker build $DOCKER_ARGS $DOKKU_DOCKER_BUILD_OPTS -t "$IMAGE" .

        plugn trigger post-build-dockerfile "$APP"
        ;;

      *)
        dokku_log_fail "Building image source type $IMAGE_SOURCE_TYPE not supported!"
        ;;
    esac
    ;;

  release)
    APP="$2"; IMAGE_SOURCE_TYPE="$3"; IMAGE_TAG="$4"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
    verify_app_name "$APP"

    case "$IMAGE_SOURCE_TYPE" in
      herokuish)
        plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG"
        if [[ -n $(config_export global) ]]; then
          id=$(config_export global | docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh")
          test "$(docker wait $id)" -eq 0
          docker commit $id $IMAGE > /dev/null
        fi
        if [[ -n $(config_export app $APP) ]]; then
          id=$(config_export app $APP | docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh")
          test "$(docker wait $id)" -eq 0
          docker commit $id $IMAGE > /dev/null
        fi
        plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG"
        ;;

      dockerfile)
        # buildstep plugins don't necessarily make sense for dockerfiles. call the new breed!!!
        plugn trigger pre-release-dockerfile "$APP" "$IMAGE_TAG"
        plugn trigger post-release-dockerfile "$APP" "$IMAGE_TAG"
        ;;

      *)
        dokku_log_fail "Releasing image source type $IMAGE_SOURCE_TYPE not supported!"
        ;;
    esac
    ;;

  trace)
    [[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p $DOKKU_ROOT/.dokkurc
    [[ "$2" == "on" ]] || [[ "$2" == "off" ]] || {
      dokku_log_fail "Valid trace options are [on/off]"
    }

    if [[ "$2" == "on" ]]; then
      echo "Enabling dokku trace"
      echo "export DOKKU_TRACE=1" > $DOKKU_ROOT/.dokkurc/DOKKU_TRACE
    fi

    if [[ "$2" == "off" ]]; then
      echo "Disabling dokku trace"
      rm -f $DOKKU_ROOT/.dokkurc/DOKKU_TRACE
    fi
    ;;

  delete)
    dokku apps:destroy $2
    ;;

  ls)
    installed_apps=$(dokku_apps)

    dokku_col_log_info1_quiet "App Name" "Container Type" "Container Id" "Status"

    for dokku_app in $installed_apps; do
      APP=$(basename $dokku_app)
      DOKKU_APP_CIDS=$(get_app_container_ids $APP)
      DOCKER_RUNNING_CONTAINERS=$(docker ps -q --no-trunc)
      if [[ -n $DOKKU_APP_CIDS ]]; then
        for DOKKU_APP_CID in $DOKKU_APP_CIDS; do
          DOKKU_APP_CONTAINER_STATUS="stopped"
          [[ $DOCKER_RUNNING_CONTAINERS =~ $DOKKU_APP_CID ]] && DOKKU_APP_CONTAINER_STATUS="running"
          DOKKU_APP_CONTAINER_TYPE=$(grep -l $DOKKU_APP_CID $DOKKU_ROOT/$APP/CONTAINER.* | awk -F '/' '{ print $5 }' | awk -F '.' '{ print $2 }')
          dokku_col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "${DOKKU_APP_CID:0:12}" "$DOKKU_APP_CONTAINER_STATUS"
        done
      else
        dokku_col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" "NOT_DEPLOYED"
      fi
    done
    ;;

  run)
    [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
    APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP); IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
    verify_app_name "$APP"

    shift 2

    DOKKU_APP_RM_CONTAINER=$(dokku config:get $APP DOKKU_RM_CONTAINER || true)
    DOKKU_GLOBAL_RM_CONTAINER=$(dokku config:get --global DOKKU_RM_CONTAINER || true)
    DOKKU_RM_CONTAINER=${DOKKU_APP_RM_CONTAINER:="$DOKKU_GLOBAL_RM_CONTAINER"}

    DOCKER_ARGS=$(: | plugn trigger docker-args-run $APP $IMAGE_TAG)
    [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
    [[ "$DOKKU_RM_CONTAINER" ]] && DOKKU_RUN_OPTS="--rm"
    has_tty && DOKKU_RUN_OPTS+=" -i -t"
    is_image_herokuish_based "$IMAGE" && EXEC_CMD="/exec"

    docker run $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
    ;;

  url | urls)
    [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
    APP="$2"; verify_app_name "$2"
    eval "$(config_export app $APP)"

    if [[ -s "$DOKKU_ROOT/$APP/URLS" ]]; then
      case "$1" in
        url)
          grep "^http" "$DOKKU_ROOT/$APP/URLS" | head -1
        ;;
        urls)
          grep "^http" "$DOKKU_ROOT/$APP/URLS"
        ;;
      esac

      exit 0
    fi

    SCHEME="http"; SSL="$DOKKU_ROOT/$APP/tls"; WILDCARD_SSL="$DOKKU_ROOT/tls"
    if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]] || [[ -e "$WILDCARD_SSL/server.crt" && -e "$WILDCARD_SSL/server.key" ]]; then
      SCHEME="https"
    fi

    if [[ "$(is_app_vhost_enabled $APP)" == "false" ]]; then
      shopt -s nullglob
      for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
        echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
      done
      shopt -u nullglob

      DOKKU_NGINX_PORT=$(config_get $APP DOKKU_NGINX_PORT || true)
      DOKKU_NGINX_SSL_PORT=$(config_get $APP DOKKU_NGINX_SSL_PORT || true)

      if [[ -n "$DOKKU_NGINX_PORT" ]]; then
        echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT (nginx)"
      fi
      if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
        echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT (nginx-ssl)"
      fi
    else
      echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
    fi
  ;;

  version)
    cat "$DOKKU_ROOT/VERSION" || dokku_log_fail "Unable to determine dokku's version"
    ;;

  help)
    cat<<EOF
    ls, Pretty listing of deployed applications and containers
    run <app> <cmd>, Run a command in the environment of an application
    trace [on/off], Enable dokku tracing
    url <app>, Show the first URL for an application (compatibility)
    urls <app>, Show all URLs for an application
    version, Print dokku's version
EOF
    ;;

  *)
    exit $DOKKU_NOT_IMPLEMENTED_EXIT
    ;;

esac
