#!/usr/bin/env bash

source "$(dirname $0)/vars"

APP="$1"; PORT="$2"; INT_PORT="$3"; IP="${4:-127.0.0.1}"
[[ "$INT_PORT" != "" ]] || INT_PORT="$APP_PORT"
WILDCARD_SSL_DIR="$DOKKU_ROOT/ssl"
WILDCARD_TLS_DIR="$DOKKU_ROOT/tls"
SSL_DIR="$DOKKU_ROOT/$APP/ssl"
TLS_DIR="$DOKKU_ROOT/$APP/tls"

if [[ "$PORT" == "" ]] || [[ -f "$DOKKU_ROOT/$APP/NO_VHOST" ]]; then
  rm -f "$DOKKU_ROOT/$APP/nginx.conf"
  pluginhook nginx-pre-reload $APP
  sudo /etc/init.d/nginx reload > /dev/null
  exit 0
fi

hostnames_for_app "$APP"

http_host() {
  [[ $# -le 1 ]] && return

  DOKKU_LISTEN_IPV4="${DOKKU_LISTEN_IPV4:-*}"
  DOKKU_LISTEN_IPV6="${DOKKU_LISTEN_IPV6:-[::]}"
  SCHEME="$1"
  shift

  cat <<EOF
server {
EOF

  if [[ "$SCHEME" == "https" ]]; then
    cat <<EOF
  listen      $DOKKU_LISTEN_IPV6:443 ssl spdy;
  listen      $DOKKU_LISTEN_IPV4:443 ssl spdy;
  server_name $@;

  keepalive_timeout   70;
  add_header Alternate-Protocol 443:npn-spdy/2;

  ssl on;
  ssl_certificate     $SSL_INUSE/server.crt;
  ssl_certificate_key $SSL_INUSE/server.key;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_session_timeout 5m;
  ssl_session_cache shared:SSL:50m;

EOF

  DOKKU_ENABLE_HSTS="$(config_get DOKKU_ENABLE_HSTS || true)"
  DOKKU_ENABLE_HSTS="${DOKKU_ENABLE_HSTS:-$DOKKU_FORCE_ENABLE_HSTS}"

  if [[ -n "$DOKKU_ENABLE_HSTS" ]] && [[ -z "$DOKKU_ENABLE_HTTP_HOST" ]]; then
    cat <<EOF
  add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

EOF
  fi

  else
    cat <<EOF
  listen      $DOKKU_LISTEN_IPV6:80;
  listen      $DOKKU_LISTEN_IPV4:80;
  server_name $@;

EOF
  fi

  cat <<EOF
  location    / {
    proxy_pass  http://$APP;
EOF

  if [[ -f "$APP_DIR/htpasswd" ]]; then
    cat <<EOF
    auth_basic "closed website";
    auth_basic_user_file "$APP_DIR/htpasswd";
EOF
    fi

  for host in "$@";
  do
    echo "proxy_redirect http://$host:$INT_PORT/ $SCHEME://$host/;"
    [[ "$SCHEME" == "https" ]] && echo "proxy_redirect https://$host:$INT_PORT/ $SCHEME://$host/;"
  done

  cat <<EOF
    proxy_http_version 1.1;
    proxy_set_header Upgrade \$http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host \$http_host;
    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
EOF

  if [[ -z "$DOKKU_DISABLE_NGINX_X_FORWARDED" ]]; then
    cat <<EOF
    proxy_set_header X-Forwarded-Proto \$scheme;
    proxy_set_header X-Forwarded-Port \$server_port;
    proxy_set_header X-Request-Start \$msec;
EOF
  fi

  DOKKU_NGINX_PROXY_READ_TIMEOUT=$(config_get DOKKU_NGINX_PROXY_READ_TIMEOUT || true)
  [[ -n "$DOKKU_NGINX_PROXY_READ_TIMEOUT" ]] && echo "    proxy_read_timeout $DOKKU_NGINX_PROXY_READ_TIMEOUT;"

  cat <<EOF
  }
  include $DOKKU_ROOT/$APP/nginx.conf.d/*.conf;
}
EOF
}

http_redirect() {
  [[ $# -le 1 ]] && return

  DOKKU_LISTEN_IPV4="${DOKKU_LISTEN_IPV4:-*}"
  DOKKU_LISTEN_IPV6="${DOKKU_LISTEN_IPV6:-[::]}"
  WHERE="$1"

  shift

  cat<<EOF
server {
  listen      $DOKKU_LISTEN_IPV6:80;
  listen      $DOKKU_LISTEN_IPV4:80;
  server_name $@;
  return 301 $WHERE;
}
EOF
}

https_redirect() {
  [[ $# -le 1 ]] && return

  DOKKU_LISTEN_IPV4="${DOKKU_LISTEN_IPV4:-*}"
  DOKKU_LISTEN_IPV6="${DOKKU_LISTEN_IPV6:-[::]}"
  WHERE="$1"

  shift

  cat<<EOF
server {
  listen      $DOKKU_LISTEN_IPV6:443 ssl spdy;
  listen      $DOKKU_LISTEN_IPV4:443 ssl spdy;
  server_name $@;
  
  ssl on;
  ssl_certificate     $SSL_INUSE/server.crt;
  ssl_certificate_key $SSL_INUSE/server.key;
  return 301 $WHERE;
}
EOF
}


cat<<EOF > $DOKKU_ROOT/$APP/nginx.conf
upstream $APP { server $IP:$PORT; }
EOF

if [[ "$hostname" != "" ]]; then
  if [[ -f "$SSL_DIR/server.crt" ]] && [[ -f "$SSL_DIR/server.key" ]]; then
    SSL_INUSE="$SSL_DIR"
  elif [[ -f "$TLS_DIR/server.crt" ]] && [[ -f "$TLS_DIR/server.key" ]]; then
    SSL_INUSE="$TLS_DIR"
  elif  [[ -f "$WILDCARD_SSL_DIR/server.crt" ]] && [[ -f "$WILDCARD_SSL_DIR/server.key" ]] && [[ $hostname = `openssl x509 -in $WILDCARD_SSL_DIR/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-` ]]; then
    SSL_INUSE="$WILDCARD_SSL_DIR"
  elif  [[ -f "$WILDCARD_TLS_DIR/server.crt" ]] && [[ -f "$WILDCARD_TLS_DIR/server.key" ]] && [[ $hostname = `openssl x509 -in $WILDCARD_TLS_DIR/server.crt -noout -subject | tr '/' '\n' | grep CN= | cut -c4-` ]]; then
    SSL_INUSE="$WILDCARD_TLS_DIR"
  fi

  # ssl based nginx.conf
  if [[ -n "$SSL_INUSE" ]]; then
    DOKKU_ENABLE_HTTP_HOST=$(config_get DOKKU_ENABLE_HTTP_HOST || true)
    if [[ -n "$DOKKU_ENABLE_HTTP_HOST" ]]; then
      http_host http ${hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf
      http_redirect "https://$hostname\$request_uri" ${redirect_hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf # we prefer https over http
      https_redirect "https://$hostname\$request_uri" ${redirect_hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf # we prefer https over http
    else
      http_redirect "https://\$host\$request_uri" ${hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf
      http_redirect "https://$hostname\$request_uri" ${redirect_hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf
      https_redirect "https://$hostname\$request_uri" ${redirect_hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf
    fi
    http_host https ${hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf

    echo "https://$hostname" > "$DOKKU_ROOT/$APP/URL"
  else
    # default nginx.conf
    http_host http ${hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf
    http_redirect "http://$hostname\$request_uri" ${redirect_hostnames[@]} >> $DOKKU_ROOT/$APP/nginx.conf

    echo "http://$hostname" > "$DOKKU_ROOT/$APP/URL"
  fi

  pluginhook nginx-pre-reload $APP
  sudo /etc/init.d/nginx reload > /dev/null
fi
