#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$(dirname $0)/../common/functions"

case "$1" in
  build)
    APP="$2"; IMAGE="dokku/$APP"; IMAGE_SOURCE_TYPE="$3"; TMP_WORK_DIR="$4"
    CACHE_DIR="$DOKKU_ROOT/$APP/cache"

    pushd "$TMP_WORK_DIR" &> /dev/null

    case "$IMAGE_SOURCE_TYPE" in
      buildstep)
        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
        # *DEPRECATED* in v0.4.0: `pluginhook pre-build` will be removed in future releases
        pluginhook pre-build "$APP"
        pluginhook pre-build-buildstep "$APP"

        # *DEPRECATED* in v0.3.14: `pluginhook docker-args` will be removed in future releases
        # https://github.com/progrium/dokku/issues/896 & https://github.com/progrium/dokku/issues/906
        DOCKER_ARGS=$(: | pluginhook docker-args $APP build)
        DOCKER_ARGS+=$(: | pluginhook docker-args-build $APP)
        id=$(docker run -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build/builder)
        docker attach $id
        test "$(docker wait $id)" -eq 0
        docker commit $id $IMAGE > /dev/null

        # *DEPRECATED* in v0.4.0: `pluginhook post-build` will be removed in future releases
        pluginhook post-build "$APP"
        pluginhook post-build-buildstep "$APP"
        ;;

      dockerfile)
        # sticking with same pattern of building app image before pre-build for now.
        docker build -t "$IMAGE" .
        # buildstep pluginhooks don't necessarily make sense for dockerfiles. call the new breed!!!
        pluginhook pre-build-dockerfile "$APP"
        pluginhook post-build-dockerfile "$APP"
        ;;

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

  release)
    APP="$2"; IMAGE="dokku/$APP"; IMAGE_SOURCE_TYPE="$3"
    case "$IMAGE_SOURCE_TYPE" in
      buildstep)
        # *DEPRECATED* in v0.4.0: `pluginhook pre-release` will be removed in future releases
        pluginhook pre-release "$APP"
        pluginhook pre-release-buildstep "$APP"
        if [[ -f "$DOKKU_ROOT/ENV" ]]; then
          id=$(docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh" < "$DOKKU_ROOT/ENV")
          test "$(docker wait $id)" -eq 0
          docker commit $id $IMAGE > /dev/null
        fi
        if [[ -f "$DOKKU_ROOT/$APP/ENV" ]]; then
          id=$(docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh" < "$DOKKU_ROOT/$APP/ENV")
          test "$(docker wait $id)" -eq 0
          docker commit $id $IMAGE > /dev/null
        fi
        # *DEPRECATED* in v0.4.0: `pluginhook post-release` will be removed in future releases
        pluginhook post-release "$APP"
        pluginhook post-release-buildstep "$APP"
        ;;

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

      *)
        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" ]] || {
      echo "Valid trace options are [on/off]"
      exit 1
    }

    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)
    apps=$(ls -d $DOKKU_ROOT/*/ 2>/dev/null) || (echo "You haven't depoyed any applications yet" && exit 1)

    dokku_col_log_info2_quiet "App Name" "Container id"

    for app in $apps; do
      if [[ -f $app/CONTAINER ]]; then
        dokku_col_log_msg "$(basename $app)" "$(< $app/CONTAINER)"
      else
        dokku_col_log_msg "$(basename $app)"
      fi
    done
    ;;

  logs)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    verify_app_name "$2"
    APP="$2";

    if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
      CONTAINER=$(<$DOKKU_ROOT/$APP/CONTAINER)
      if [[ $3 == "-t" ]]; then
        docker logs --follow $CONTAINER
      else
        docker logs $CONTAINER | tail -n 100
      fi
    else
      echo "Application's container not found"
    fi
    ;;

  run)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    verify_app_name "$2"
    APP="$2"; IMAGE="dokku/$APP"

    shift 2

    DOCKER_ARGS=$(: | pluginhook docker-args $APP run)
    DOCKER_ARGS+=$(: | pluginhook docker-args-run $APP)
    [[ $DOKKU_RM_CONTAINER ]] && DOKKU_RUN_OPTS="--rm"
    has_tty && DOKKU_RUN_OPTS+=" -i -t"
    is_image_buildstep_based "$IMAGE" && EXEC_CMD="/exec"

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

  url | urls)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    verify_app_name "$2"
    APP="$2";

    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 [[ -f "$DOKKU_ROOT/VHOST" ]]; then
      echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
    else
      echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$DOKKU_ROOT/$APP/PORT")"
    fi
  ;;

  version)
    cat "$DOKKU_ROOT/VERSION" || {
      echo "Unable to determine dokku's version" 2>&1
      exit 1
    }
    ;;

  help)
    cat && cat<<EOF
    ls                                              Pretty listing of deployed applications and containers
    logs <app> [-t]                                 Show the last logs for an application (-t follows)
    run <app> <cmd>                                 Run a command in the environment of an application
    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
