#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

RE_IPV4="([0-9]{1,3}[\.]){3}[0-9]{1,3}"

RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|"                    # TEST: 1:2:3:4:5:6:7:8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|"                         # TEST: 1::                              1:2:3:4:5:6:7::
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|"         # TEST: 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|"  # TEST: 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|"  # TEST: 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|"  # TEST: 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|"  # TEST: 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|"       # TEST: 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|"                     # TEST: ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|"     # TEST: fe08::7:8%eth0      fe08::7:8%1                                      (link-local IPv6 addresses with zone index)
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|"            # TEST: ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}"                # TEST: 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33

domains_restart_app() {
  APP="$1";

  if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]]; then
    echo "-----> Releasing $APP ..."
    dokku release $APP
    echo "-----> Release complete!"
    echo "-----> Deploying $APP ..."
    dokku deploy $APP
    echo "-----> Deploy complete!"
  fi
}

case "$1" in
  domains)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    [[ ! -d "$DOKKU_ROOT/$2" ]] && echo "App $2 does not exist" && exit 1
    APP="$2"

    dokku domains:setup $APP
    echo "=== $APP Domain Names"
    cat "$DOKKU_ROOT/$APP/VHOST"
    ;;

  domains:setup)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    [[ ! -d "$DOKKU_ROOT/$2" ]] && echo "App $2 does not exist" && exit 1
    APP="$2"; VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"

    if [[ ! -f $VHOST_PATH ]]; then
      if [[ -f "$DOKKU_ROOT/VHOST" ]];then
        VHOST=$(< "$DOKKU_ROOT/VHOST")
      else
        VHOST=$(< "$DOKKU_ROOT/HOSTNAME")
      fi
      if [[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]];then
        echo "unsupported vhost config found. disabling vhost support"
        [[ ! $(grep -q NO_VHOST "$DOKKU_ROOT/$APP/ENV") ]] && echo "export NO_VHOST='1'" >> "$DOKKU_ROOT/$APP/ENV"
      else
        if [[ -f "$DOKKU_ROOT/VHOST" ]]; then
          echo "-----> Creating new $VHOST_PATH..."
          SUBDOMAIN=${APP/%\.${VHOST}/}
          hostname=$(: | pluginhook nginx-hostname $APP $SUBDOMAIN $VHOST)
          if [[ ! -n $hostname ]]; then
            if [[ "$APP" == *.* ]] && [[ "$SUBDOMAIN" == "$APP" ]]; then
              hostname="${APP/\//-}"
            else
              hostname="${APP/\//-}.$VHOST"
            fi
          fi

          echo "$hostname" > $VHOST_PATH
        fi
      fi
    fi
    ;;

  domains:add)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    [[ ! -d "$DOKKU_ROOT/$2" ]] && echo "App $2 does not exist" && exit 1
    APP="$2"

    if [[ -z $3 ]]; then
      echo "Usage: dokku $1 $APP DOMAIN"
      echo "Must specify DOMAIN."
      exit 1
    fi

    if [[ $(egrep ^"$3"$ "$DOKKU_ROOT/$APP/VHOST" > /dev/null 2>&1; echo $?) -eq 0 ]]; then
      echo "$3 is already defined for $APP"
      exit 1
    fi

    dokku domains:setup $APP
    echo "$3" >> "$DOKKU_ROOT/$APP/VHOST"
    # we need to restart the app to make sure we're binding to the appropriate network interface
    domains_restart_app $APP
    pluginhook post-domains-update $APP
    echo "-----> Added $3 to $APP"

    ;;

  domains:clear)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    [[ ! -d "$DOKKU_ROOT/$2" ]] && echo "App $2 does not exist" && exit 1
    APP="$2"

    rm -f "$DOKKU_ROOT/$APP/VHOST"
    dokku domains:setup $APP
    pluginhook post-domains-update $APP
    echo "-----> Cleared domains in $APP"

    ;;

  domains:remove)
    [[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
    [[ ! -d "$DOKKU_ROOT/$2" ]] && echo "App $2 does not exist" && exit 1
    APP="$2"

    if [[ -z $3 ]]; then
      echo "Usage: dokku $1 $2 DOMAIN"
      echo "Must specify DOMAIN."
      exit 1
    fi

    dokku domains:setup $APP
    sed -i "/^$3$/d" "$DOKKU_ROOT/$APP/VHOST"
    pluginhook post-domains-update $APP
    echo "-----> Removed $3 from $APP"

    ;;

  help | domains:help)
    cat && cat<<EOF
    domains <app>                                   List custom domains for app
    domains:add <app> DOMAIN                        Add a custom domain to app
    domains:clear <app>                             Clear all custom domains for app
    domains:remove <app> DOMAIN                     Remove a custom domain from app
EOF
    ;;

  *)
    exit $DOKKU_NOT_IMPLEMENTED_EXIT
    ;;

esac
