#!/usr/bin/env bash
set -euo pipefail
umask 077
command -v docker >/dev/null
command -v openssl >/dev/null
docker info >/dev/null
port=${CLIENT_LAB_PORT:-15432}
[[ "$port" =~ ^[0-9]+$ ]] && ((port >= 1024 && port <= 65535)) || exit 1
# 合成凭据与导出物放在仅当前用户可访问的临时目录，避免落入源码仓库或同步目录。
lab=$(mktemp -d /tmp/client-lab.XXXXXX)
name=${lab##*/}
volume="$name-data"
printf '实验目录：%s\n容器：%s\n' "$lab" "$name"
mkdir "$lab/secrets"
for role in admin writer reader; do openssl rand -hex 24 > "$lab/secrets/$role.password"; done
docker container inspect "$name" >/dev/null 2>&1 && exit 1
docker volume inspect "$volume" >/dev/null 2>&1 && exit 1
docker volume create --label article-lab=data-client --label "lab-name=$name" "$volume" >/dev/null
POSTGRES_PASSWORD=$(<"$lab/secrets/admin.password") \
docker run -d --name "$name" --label article-lab=data-client \
  --label "lab-name=$name" -p "127.0.0.1:$port:5432" \
  -e POSTGRES_DB=client_lab \
  -e POSTGRES_PASSWORD \
  --mount "type=volume,src=$volume,dst=/var/lib/postgresql" \
  postgres:18.6 >/dev/null
ready=false
for attempt in $(seq 1 60); do
  if docker exec "$name" pg_isready -h 127.0.0.1 -U postgres -d client_lab >/dev/null 2>&1; then
    ready=true; break
  fi
  sleep 1
done
if test "$ready" != true; then docker logs "$name" --tail 60; exit 1; fi
writer=$(<"$lab/secrets/writer.password")
reader=$(<"$lab/secrets/reader.password")
docker exec -i "$name" psql -U postgres -d client_lab -v ON_ERROR_STOP=1 <<SQL
CREATE ROLE lab_writer LOGIN PASSWORD '$writer';
CREATE ROLE lab_reader LOGIN PASSWORD '$reader';
CREATE SCHEMA lab AUTHORIZATION lab_writer;
GRANT CONNECT ON DATABASE client_lab TO lab_writer, lab_reader;
GRANT USAGE ON SCHEMA lab TO lab_reader;
ALTER ROLE lab_writer IN DATABASE client_lab SET search_path=lab,public;
ALTER ROLE lab_reader IN DATABASE client_lab SET search_path=lab,public;
SET ROLE lab_writer;
CREATE TABLE lab.client_guard_lab(
  id integer PRIMARY KEY,
  status varchar(24) NOT NULL,
  created_at timestamptz NOT NULL DEFAULT current_timestamp
);
INSERT INTO lab.client_guard_lab(id,status) VALUES(1,'CREATED'),(2,'PAID'),(3,'CREATED');
GRANT SELECT ON lab.client_guard_lab TO lab_reader;
RESET ROLE;
SQL
unset writer reader
printf 'LAB_NAME=%q\nLAB_VOLUME=%q\nLAB_PORT=%q\n' "$name" "$volume" "$port" > "$lab/state.env"
printf '就绪：127.0.0.1:%s / client_lab / lab\n写账号 lab_writer；读账号 lab_reader；密码仅在 %s/secrets/\n' "$port" "$lab"
