#!/usr/bin/env bash

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly ROOT
readonly IMAGE="hugo-chiri-ops-01"
readonly NETWORK="hugo-chiri-ops-01-network"
readonly METRIC_CONTAINER="ops-01-metric-source"
readonly PROMETHEUS_CONTAINER="ops-01-prometheus"
readonly FAILURE_COLLECTOR="ops-01-failure-collector"
readonly PROMETHEUS_IMAGE="prom/prometheus:v3.12.0@sha256:69f5241418838263316593f7274a304b095c40bcf22e57272865da91bd60a8ac"
readonly COLLECTOR_IMAGE="otel/opentelemetry-collector:0.155.0@sha256:140cdb56eeea12ebc33bb4f7109fd4eef90391933f8d85b33384fcfe1cf040c4"
readonly RESULTS="${ROOT}/results"

cleanup() {
  docker rm --force "${METRIC_CONTAINER}" "${PROMETHEUS_CONTAINER}" \
    "${FAILURE_COLLECTOR}" >/dev/null 2>&1 || true
  docker network rm "${NETWORK}" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM

cd "${ROOT}"
cleanup
docker build --tag "${IMAGE}" .
if [[ "${RESULTS}" != "${ROOT}/results" ]]; then
  echo "refusing to clear an unexpected results directory" >&2
  exit 65
fi
rm -rf "${RESULTS}"
mkdir -p "${RESULTS}"

docker run --rm \
  --cpus=2 \
  --memory=512m \
  --volume "${RESULTS}:/experiment/results" \
  "${IMAGE}"
docker run --rm \
  --cpus=2 \
  --memory=512m \
  --volume "${RESULTS}:/experiment/results" \
  --entrypoint node \
  "${IMAGE}" verify-profile.mjs

docker network create "${NETWORK}" >/dev/null
docker run --detach \
  --name "${METRIC_CONTAINER}" \
  --network "${NETWORK}" \
  --entrypoint node \
  "${IMAGE}" metric-source.mjs >/dev/null
docker run --detach \
  --name "${PROMETHEUS_CONTAINER}" \
  --network "${NETWORK}" \
  --volume "${ROOT}/prometheus-integration.yaml:/etc/prometheus/prometheus.yml:ro" \
  --volume "${ROOT}/prometheus-integration-rules.yaml:/etc/prometheus/prometheus-integration-rules.yaml:ro" \
  "${PROMETHEUS_IMAGE}" \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/prometheus \
  --storage.tsdb.retention.time=15m >/dev/null
docker run --rm \
  --network "${NETWORK}" \
  --volume "${RESULTS}:/experiment/results" \
  --entrypoint node \
  "${IMAGE}" observe-alerts.mjs

docker run --detach \
  --name "${FAILURE_COLLECTOR}" \
  --network "${NETWORK}" \
  --volume "${ROOT}/collector-failure.yaml:/etc/otelcol/config.yaml:ro" \
  "${COLLECTOR_IMAGE}" --config=/etc/otelcol/config.yaml >/dev/null
docker run --rm \
  --network "${NETWORK}" \
  --volume "${RESULTS}:/experiment/results" \
  --entrypoint node \
  "${IMAGE}" exercise-export-failure.mjs
docker run --rm \
  --entrypoint promtool \
  "${IMAGE}" test rules prometheus-rules.test.yaml \
  >"${RESULTS}/promtool.txt.tmp" 2>&1
sed -E -e 's/[[:space:]]+$//' -e '${/^$/d;}' \
  "${RESULTS}/promtool.txt.tmp" >"${RESULTS}/promtool.txt"
rm "${RESULTS}/promtool.txt.tmp"
docker run --rm \
  --volume "${ROOT}/collector.yaml:/etc/otelcol/config.yaml:ro" \
  "${COLLECTOR_IMAGE}" validate --config=/etc/otelcol/config.yaml \
  >"${RESULTS}/collector-validation.txt" 2>&1
printf '%s\n' \
  'command=otelcol validate --config=/etc/otelcol/config.yaml' \
  'exit_code=0' >>"${RESULTS}/collector-validation.txt"

set +e
docker run --rm \
  --volume "${ROOT}/collector-invalid.yaml:/etc/otelcol/config.yaml:ro" \
  "${COLLECTOR_IMAGE}" validate --config=/etc/otelcol/config.yaml \
  >"${RESULTS}/collector-invalid.txt" 2>&1
invalid_exit=$?
set -e
if [[ ${invalid_exit} -eq 0 ]]; then
  echo "invalid Collector configuration unexpectedly passed" >&2
  exit 1
fi
printf 'exit_code=%s\n' "${invalid_exit}" >>"${RESULTS}/collector-invalid.txt"

docker run --rm \
  --volume "${RESULTS}:/experiment/results" \
  --entrypoint sh \
  "${IMAGE}" -lc \
  'mkdir -p results/environment && npm audit --audit-level=low > results/environment/npm-audit.txt 2>&1'
docker run --rm \
  --volume "${RESULTS}:/experiment/results" \
  --entrypoint sh \
  "${IMAGE}" -lc \
  'node source-evidence.mjs && node disposition-record.mjs && node source-manifest.mjs && node mutate.mjs && node verify-results.mjs'
