#!/bin/bash

set -eu

DOCKER_WEB_IMAGE_NAME="ghcr.io/opdavies/${COMPOSE_PROJECT_NAME:-oliverdavies.uk}-web"

TTY=""
if [[ ! -t 1 ]]; then
  TTY="-T"
fi

DC="${DC:-exec}"

function ci:build-images {
  docker image build . \
    --tag ${DOCKER_WEB_IMAGE_NAME}:${DOCKER_TAG} \
    --tag ${DOCKER_WEB_IMAGE_NAME}:latest \
    --target=production
}

function ci:push-images {
  docker image push ${DOCKER_WEB_IMAGE_NAME}:${DOCKER_TAG}
  docker image push ${DOCKER_WEB_IMAGE_NAME}:latest
}

function cmd {
  # Run any command in the app container.
  _dc app "${@}"
}

function composer {
  DC=run
  _dc --entrypoint composer app "${@}"
}

function deploy {
  cd tools/deployment
  ansible-playbook deploy.yml "${@}"
}

function help {
  printf "%s <task> [args]\n\nTasks:\n" "${0}"

  compgen -A function | grep -v "^_" | cat -n

  printf "\nExtended help:\n  Each task has comments for general usage\n"
}

function markdownlint:build {
  docker image build . \
    -f markdownlint.Dockerfile \
    -t markdownlint
}

function markdownlint:run {
  docker container run --rm \
    -v $(pwd)/.markdownlint.yaml:/root/.markdownlint.yaml \
    -v $(pwd)/source:/data \
    markdownlint
}

function run-production {
  DESTINATION_PATH="${2:-/var/www/oliverdavies.uk}"
  GIT_COMMIT_HASH="${1:-latest}"

  # Clean up any old containers or files within the artifact directory.
  rm -fr ${DESTINATION_PATH}/* || true

  docker image pull ghcr.io/opdavies/oliverdavies-uk-web:${GIT_COMMIT_HASH}

  docker container run \
    --entrypoint sh \
    --name oliverdavies-uk-web \
    ghcr.io/opdavies/oliverdavies-uk-web:${GIT_COMMIT_HASH}

  docker container cp oliverdavies-uk-web:/code/. ${DESTINATION_PATH}

  docker container rm oliverdavies-uk-web
}

function sh {
  DC=run
  _dc --entrypoint sh app
}

function test:quality {
  DC=run
  _dc --entrypoint phpstan app "${@}" analyze --memory-limit=-1
}

function test:unit {
  DC=run
  _dc --entrypoint phpunit app "${@}"
}

function yarn:build:css {
  # Build CSS assets, this is meant to be run from within the assets container.
  local args=()

  if [ "${SCULPIN_ENV}" == "prod" ]; then
    args=(--minify)
  elif [ "${NODE_ENV}" == "development" ]; then
    args=(--watch)
  fi

  tailwindcss --postcss -i assets/css/tailwind.pcss -o build/app.css "${args[@]}"
}

function yarn:build:js {
  # Build JS assets, this is meant to be run from within the assets container.
  node esbuild.config.js
}

function _dc {
  docker-compose ${DC} ${TTY} "${@}"
}

eval "${@:-help}"