#!/bin/bash

CWD="$(pwd)"
ARGUMENTS="$@"
# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within
DIRNAME="$(dirname "$(readlink -f "$0")")"

DOCKER="docker"
set +e
# $DOCKER ps >/dev/null 2>&1
# if [ $? != 0 ]; then
#   DOCKER="sudo docker"
# fi
if ! $DOCKER ps >/dev/null; then
  echo "error connecting to docker:"
  $DOCKER ps
  exit 1
fi
set -e

set -o errexit -o pipefail -o noclobber -o nounset

TARGET=-
INPUT=input
OUTPUT=output
NAME=name
ARCH=name

TARGET_VERSION=-
DEBIAN_RELEASE=buster
CACHE=y

INPUT_NAME=name

NEXT_ARGUMENTS=""
while true; do
  if [ "$#" == "0" ]
  then break
  fi

  case "$1" in
    -d|--docker)
      shift
      ;;
    -t|--target)
      TARGET="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1" "$2")"
      shift 2
      ;;
    -i|--input)
      INPUT="$2"
      INPUT_NAME="$(basename "$2")"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "--input input")"
      shift 2
      ;;
    -o|--output)
      OUTPUT="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "--output output")"
      shift 2
      ;;
    -n|--name)
      NAME="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1" "$2")"
      shift 2
      ;;
    -a|--arch)
      ARCH="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1" "$2")"
      shift 2
      ;;
    --target-version)
      TARGET_VERSION="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1" "$2")"
      shift 2
      ;;
    --debian-release)
      DEBIAN_RELEASE="$2"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1" "$2")"
      shift 2
      ;;
    --no-cache)
      CACHE="n"
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1")"
      shift
      ;;
    *)
      NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "$1")"
      shift
      ;;
  esac
done

if [ "${NAME}" == "name" ]
then
  NAME="${INPUT_NAME}"
fi

if [ "${TARGET_VERSION}" == "-" ]
then
  if [ "${TARGET}" == "nodejs" ]
  then
    TARGET_VERSION=10
  else
    TARGET_VERSION=0
  fi
fi

NEXT_ARGUMENTS="${NEXT_ARGUMENTS} $(echo -n "--name ${NAME}")"

BASE_IMAGE_NAME=${BASE_IMAGE_NAME:-debian-package-builder}
TARGET_IMAGE_NAME=${TARGET_IMAGE_NAME:-debian-${TARGET}-package-builder}
CONTAINER_NAME=${CONTAINER_NAME:-debian-${TARGET}-package-builder-${ARCH}-work}

CONTAINER_RUNNING=$($DOCKER ps --filter name="$CONTAINER_NAME" -q)
if [ "$CONTAINER_RUNNING" != "" ]; then
  echo "The build is already running in container $CONTAINER_NAME. Aborting."
  exit 1
fi

CONTAINER_EXISTS=$($DOCKER ps -a --filter name="$CONTAINER_NAME" -q)
if [ "$CONTAINER_EXISTS" != "" ]; then
  $DOCKER rm -v "${CONTAINER_NAME}"
fi

function cleanup {
  echo 'got EXIT signal... please wait'

  $DOCKER stop debian-package-builder-apt-cache > /dev/null
  $DOCKER rm -v debian-package-builder-apt-cache > /dev/null

  if [ "${TARGET}" == "nodejs" ]; then
    $DOCKER stop debian-package-builder-npm-cache > /dev/null
    $DOCKER rm -v debian-package-builder-npm-cache > /dev/null
  fi

  CONTAINER_RUNNING=$($DOCKER ps --filter name="${CONTAINER_NAME}" -q)
  if [ "${CONTAINER_RUNNING}" != "" ]; then
    $DOCKER stop ${CONTAINER_NAME} > /dev/null
  fi

  CONTAINER_EXISTS=$($DOCKER ps -a --filter name="${CONTAINER_NAME}" -q)
  if [ "${CONTAINER_EXISTS}" != "" ]; then
    $DOCKER rm -v ${CONTAINER_NAME} > /dev/null
  fi
}

trap cleanup EXIT

docker run --rm --privileged multiarch/qemu-user-static:register --reset

# start caches
#

# apt cache
$DOCKER run \
  --name debian-package-builder-apt-cache \
  --init -d \
  --publish 3142:3142 \
  --volume ${CWD}/${OUTPUT}/cache/apt:/var/cache/apt-cacher-ng \
  sameersbn/apt-cacher-ng:3.1-1

if [ "${TARGET}" == "nodejs" ]
then
  $DOCKER build \
    -t runk/npm-proxy-cache \
    github.com/runk/npm-proxy-cache#v2.2.0

  $DOCKER run \
    --name debian-package-builder-npm-cache \
    --init -d \
    --publish 3143:3143 \
    --volume ${CWD}/${OUTPUT}/cache/npm:/opt/npm-proxy-cache/cache \
    runk/npm-proxy-cache \
    --port 3143 \
    --host 0.0.0.0 \
    --expired
fi

# end caches

# start images
#

echo cache: ${CACHE}

# build base image
$DOCKER build \
  --build-arg ARCH="${ARCH}" \
  --build-arg DEBIAN_RELEASE="${DEBIAN_RELEASE}" \
  --build-arg CACHE="${CACHE}" \
  -t ${BASE_IMAGE_NAME}:${ARCH}-${DEBIAN_RELEASE} \
  -f ${DIRNAME}/docker/base.Dockerfile \
  ${DIRNAME}

# build target image
$DOCKER build \
  --build-arg ARCH="${ARCH}" \
  --build-arg DEBIAN_RELEASE="${DEBIAN_RELEASE}" \
  --build-arg TARGET_VERSION="${TARGET_VERSION}" \
  --build-arg CACHE="${CACHE}" \
  -t ${TARGET_IMAGE_NAME}:${ARCH}-${DEBIAN_RELEASE}-${TARGET_VERSION} \
  -f ${DIRNAME}/docker/${TARGET}.Dockerfile \
  ${DIRNAME}

# end images

# start container
#

CONTAINER_ARGS=

if [ "${CACHE}" == "y" ] && [ "${TARGET}" == "nodejs" ]
then
  CONTAINER_ARGS="${CONTAINER_ARGS} -e NODE_TLS_REJECT_UNAUTHORIZED=0"
fi

echo $INPUT
$DOCKER create \
  --name "${CONTAINER_NAME}" \
  --privileged \
  ${CONTAINER_ARGS} \
  ${TARGET_IMAGE_NAME}:${ARCH}-${DEBIAN_RELEASE}-${TARGET_VERSION} \
  bash -e -o errexit -o pipefail -o noclobber -o nounset -c "
    cd /app; ./build ${NEXT_ARGUMENTS};
  "
$DOCKER cp "${CWD}/${INPUT}/." "${CONTAINER_NAME}":/app/input
$DOCKER start "${CONTAINER_NAME}"
time $DOCKER logs "${CONTAINER_NAME}" --follow || true &
wait "$!"

echo "copying results from output/"
$DOCKER cp "${CONTAINER_NAME}":/app/output/. "${OUTPUT}"
ls -lah output

echo "Done! Your image(s) should be in output/"
