#!/usr/bin/env bash

set -ex

export TMP_HOME=${PWD}
export GOROOT=/usr/local/go
export PATH=${GOROOT}/bin:${PATH}

# Update to concourse 2.7.3 and garden-runc 1.4.0 caused inigo to fail since
# resolv.conf is now bind-mounted in. Removing the apt-get install, two inigo
# tests were failing because they were unable to resolve DNS names.
echo "nameserver 8.8.8.8" >> /etc/resolv.conf

# Setup DNS for *.service.cf.internal, used by the Diego components, and
# *.test.internal, used by the collocated DUSTs as a routable domain.
function setup_dnsmasq() {
  local host_addr
  host_addr=$(ip route get 8.8.8.8 | head -n1 | awk '{print $NF}')

  dnsmasq --address=/service.cf.internal/127.0.0.1 --address=/test.internal/${host_addr}
  echo -e "nameserver $host_addr\n$(cat /etc/resolv.conf)" > /etc/resolv.conf
}

build_gardenrunc () {
  echo "Building garden-runc"
  export GARDEN_GOPATH=$1

  pushd ${GARDEN_GOPATH}
    export GOPATH=${PWD}
    export PATH=${GOPATH}/bin:${PATH}
    export GARDEN_BINPATH=${PWD}/bin/

    mkdir -p $GOPATH/bin
    NSTAR_PATH=src/code.cloudfoundry.org/guardian/rundmc/nstar

    gcc -static -o $GOPATH/bin/init $GOPATH/src/code.cloudfoundry.org/guardian/cmd/init/init.c
    go install code.cloudfoundry.org/guardian/cmd/dadoo/
    go install code.cloudfoundry.org/grootfs/store/filesystems/overlayxfs/tardis

    pushd src/github.com/opencontainers/runc
      PKG_CONFIG_PATH=/usr/local/lib/pkgconfig GOPATH=${PWD}/Godeps/_workspace:${GOPATH} BUILDTAGS="seccomp" make static
      mv runc ${GARDEN_BINPATH}
    popd

    pushd $NSTAR_PATH
      make && cp nstar ${GARDEN_BINPATH}
    popd
  popd
}

create_garden_storage() {
  # Configure cgroup
  mount -t tmpfs cgroup_root /sys/fs/cgroup
  mkdir -p /sys/fs/cgroup/devices
  mkdir -p /sys/fs/cgroup/memory

  mount -tcgroup -odevices cgroup:devices /sys/fs/cgroup/devices
  devices_mount_info=$(cat /proc/self/cgroup | grep devices)
  devices_subdir=$(echo $devices_mount_info | cut -d: -f3)

  # change permission to allow us to run mknod later
  echo 'b 7:* rwm' > /sys/fs/cgroup/devices/devices.allow
  echo 'b 7:* rwm' > /sys/fs/cgroup/devices${devices_subdir}/devices.allow

  # Setup loop devices
  for i in {0..256}
  do
    rm -f /dev/loop$i
    mknod -m777 /dev/loop$i b 7 $i
  done

  # Make XFS volume
  truncate -s 8G /xfs_volume
  mkfs.xfs -b size=4096 /xfs_volume

  # Mount XFS
  mkdir /mnt/garden-storage
  mount -t xfs -o pquota,noatime,nobarrier /xfs_volume /mnt/garden-storage
  chmod 777 -R /mnt/garden-storage

  umount /sys/fs/cgroup/devices
}

build_grootfs () {
  echo "Building grootfs..."
  export GROOTFS_GOPATH=${PWD}/garden-runc-release
  export GROOTFS_BINPATH=${GROOTFS_GOPATH}/bin
  mkdir -p ${GROOTFS_BINPATH}

  pushd ${GROOTFS_GOPATH}/src/code.cloudfoundry.org/grootfs
    export GOPATH=${GROOTFS_GOPATH}
    export PATH=${GOPATH}/bin:${PATH}

    # Set up btrfs volume and loopback devices in environment
    create_garden_storage
    umount /sys/fs/cgroup

    make

    mv grootfs ${GROOTFS_GOPATH}/bin/
    mv drax /usr/local/bin
    chown root:root /usr/local/bin/drax
    chmod u+s /usr/local/bin/drax

    echo "grootfs installed."

    groupadd iamgroot -g 4294967294
    useradd iamgroot -u 4294967294 -g 4294967294
    echo "iamgroot:1:4294967293" > /etc/subuid
    echo "iamgroot:1:4294967293" > /etc/subgid
  popd
}

set_garden_rootfs () {
  # use the 1.29 version of tar that's installed in the inigo-ci docker image
  ln -sf /usr/local/bin/tar "${GARDEN_BINPATH}"

  tar cpf /tmp/rootfs.tar -C /opt/inigo/rootfs .
  export GARDEN_ROOTFS=/tmp/rootfs.tar
}

setup_gopath() {
  pushd $1

  bosh sync-blobs


  if [ -d "$1/blobs/proxy" ]; then
    mkdir /tmp/envoy
    tar -C /tmp/envoy -xf blobs/proxy/envoy*.tgz
    export ENVOY_PATH=/tmp/envoy
    chmod 777 $ENVOY_PATH
  fi

  export GOPATH_ROOT=$PWD

  export GOPATH=${GOPATH_ROOT}
  export PATH=${GOPATH_ROOT}/bin:${PATH}

  # install application dependencies
  echo "Installing go dependencies ..."
  for package in github.com/apcera/gnatsd; do
    go install $package
  done

  go install github.com/onsi/ginkgo/ginkgo
  popd
}

setup_database() {
  orig_ca_file="${GOPATH_ROOT}/src/code.cloudfoundry.org/inigo/fixtures/certs/sql-certs/server-ca.crt"
  orig_cert_file="${GOPATH_ROOT}/src/code.cloudfoundry.org/inigo/fixtures/certs/sql-certs/server.crt"
  orig_key_file="${GOPATH_ROOT}/src/code.cloudfoundry.org/inigo/fixtures/certs/sql-certs/server.key"

  ca_file="/tmp/server-ca.crt"
  cert_file="/tmp/server.crt"
  key_file="/tmp/server.key"

  # do not chown/chmod files in the inigo repo that is annoying
  cp $orig_ca_file $ca_file
  cp $orig_cert_file $cert_file
  cp $orig_key_file $key_file

  chmod 0600 "$ca_file"
  chmod 0600 "$cert_file"
  chmod 0600 "$key_file"

  if [ "${SQL_FLAVOR}" = "mysql" ]; then
    source ${GOPATH_ROOT}/scripts/ci/initialize_mysql.sh

    sed -i 's/#max_connections.*= 100/max_connections = 2000/g' /etc/mysql/mysql.conf.d/mysqld.cnf

    chown mysql:mysql "$ca_file"
    chown mysql:mysql "$cert_file"
    chown mysql:mysql "$key_file"

    sed -i "s%# ssl-cert=/etc/mysql/server-cert.pem%ssl-cert=$cert_file%g" /etc/mysql/mysql.conf.d/mysqld.cnf
    sed -i "s%# ssl-key=/etc/mysql/server-key.pem%ssl-key=$key_file%g" /etc/mysql/mysql.conf.d/mysqld.cnf
    sed -i "s%# ssl-ca=/etc/mysql/cacert.pem%ssl-ca=$ca_file%g" /etc/mysql/mysql.conf.d/mysqld.cnf
    initialize_mysql
  else
    sed -i 's/max_connections = 100/max_connections = 2000/g' /etc/postgresql/9.4/main/postgresql.conf

    chown postgres:postgres "$ca_file"
    chown postgres:postgres "$cert_file"
    chown postgres:postgres "$key_file"

    sed -i 's/ssl = false/ssl = true/g' /etc/postgresql/9.4/main/postgresql.conf
    sed -i "s%ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'%ssl_cert_file = '$cert_file'%g" /etc/postgresql/9.4/main/postgresql.conf
    sed -i "s%ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'%ssl_key_file = '$key_file'%g" /etc/postgresql/9.4/main/postgresql.conf
    sed -i "s%#ssl_ca_file = ''%ssl_ca_file = '$ca_file'%g" /etc/postgresql/9.4/main/postgresql.conf

    service postgresql start
  fi
}

setup_dnsmasq

build_gardenrunc $PWD/garden-runc-release

build_grootfs

# setup v0 env vars for dusts-v2
if [ -d $PWD/diego-release-v0 ]; then
    setup_gopath $PWD/diego-release-v0
    export GOPATH_V0=${GOPATH_ROOT}
    export AUCTIONEER_GOPATH_V0=${GOPATH_ROOT}
    export BBS_GOPATH_V0=${GOPATH_ROOT}
    export HEALTHCHECK_GOPATH_V0=${GOPATH_ROOT}
    export REP_GOPATH_V0=${GOPATH_ROOT}
    export ROUTE_EMITTER_GOPATH_V0=${GOPATH_ROOT}
    export SSHD_GOPATH_V0=${GOPATH_ROOT}
    export SSH_PROXY_GOPATH_V0=${GOPATH_ROOT}
fi

export ROUTER_GOPATH="$PWD/routing-release"
export ROUTING_API_GOPATH=${ROUTER_GOPATH}

setup_gopath $PWD/diego-release
set_garden_rootfs

export APP_LIFECYCLE_GOPATH=${GOPATH_ROOT}
export AUCTIONEER_GOPATH=${GOPATH_ROOT}
export BBS_GOPATH=${GOPATH_ROOT}
export FILE_SERVER_GOPATH=${GOPATH_ROOT}
export HEALTHCHECK_GOPATH=${GOPATH_ROOT}
export LOCKET_GOPATH=${GOPATH_ROOT}
export REP_GOPATH=${GOPATH_ROOT}
export ROUTE_EMITTER_GOPATH=${GOPATH_ROOT}
export SSHD_GOPATH=${GOPATH_ROOT}
export SSH_PROXY_GOPATH=${GOPATH_ROOT}

# used for routing to apps; same logic that Garden uses.
EXTERNAL_ADDRESS=$(ip route get 8.8.8.8 | sed 's/.*src\s\(.*\)\s/\1/;tx;d;:x')
export EXTERNAL_ADDRESS

setup_database

# display ginkgo dots properly
export LESSCHARSET=utf-8

export GARDEN_GRAPH_PATH=/tmp/aufs_mount
mkdir -p "${GARDEN_GRAPH_PATH}"
mount -t tmpfs tmpfs "${GARDEN_GRAPH_PATH}"

# workaround until Concourse's garden sets this up for us
if ! grep -qs '/sys' /proc/mounts; then
  mount -t sysfs sysfs /sys
fi

# shellcheck source=/dev/null
source "${GARDEN_GOPATH}/ci/scripts/device-control"
permit_device_control
create_loop_devices 256
