#!/bin/bash
# Greenfield bootstrap for exchange.hacktivism.ch (GOA exploration currency).
# Run as root inside container. Not for daily ops — use start_base + start_exchange.
#
# Writes:
#   /etc/taler-exchange/exchange-overrides.conf
#   /etc/taler-exchange/conf.d/exchange-coins.conf
# Ensures main conf inlines exchange-overrides.conf (merchant pattern).
# Does NOT use conf.d/zz-*.
#
# After this: offline denom sign + wire still required for /keys withdraw.

set -euo pipefail
CONF=/etc/taler-exchange/taler-exchange.conf
OV=/etc/taler-exchange/exchange-overrides.conf
COINS=/etc/taler-exchange/conf.d/exchange-coins.conf
export DEBIAN_FRONTEND=noninteractive

if [ "$(id -u)" -ne 0 ]; then
  echo "Run as root" >&2
  exit 1
fi

echo "=== 1. postgres ==="
/etc/init.d/postgresql start
sleep 2
pg_isready || true

echo "=== 2. master key (offline user) ==="
mkdir -p /var/lib/taler-exchange/offline
chown -R taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange/offline
chown taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange 2>/dev/null || true
OUT=$(runuser -u taler-exchange-offline -- taler-exchange-offline -c "$CONF" setup 2>&1) || true
echo "$OUT"
MASTER_PUB=$(echo "$OUT" | grep -oE '[A-Z0-9]{40,}' | tail -1)
if [ -z "${MASTER_PUB:-}" ]; then
  echo "ERROR: no master public key from offline setup" >&2
  exit 1
fi
echo "MASTER_PUBLIC_KEY=$MASTER_PUB"
ATTR_KEY=$(openssl rand -hex 32)
SECRETS_DIR=/etc/taler-exchange/secrets
mkdir -p "$SECRETS_DIR"
cat >"$SECRETS_DIR/exchange-attribute-encryption.secret.conf" <<SEOF
# generated by exchange-bootstrap.sh
[exchange]
ATTRIBUTE_ENCRYPTION_KEY = ${ATTR_KEY}
SEOF
chmod 640 "$SECRETS_DIR/exchange-attribute-encryption.secret.conf"
chown root:taler-exchange-httpd "$SECRETS_DIR/exchange-attribute-encryption.secret.conf" 2>/dev/null || true

echo "=== 3. exchange-overrides.conf (site; not zz-*) ==="
# Ensure main conf inlines overrides (merchant pattern)
if ! grep -q 'exchange-overrides.conf' "$CONF" 2>/dev/null; then
  printf '\n# Manual site overrides (merchant pattern)\n@inline@ exchange-overrides.conf\n' >>"$CONF"
fi
# Remove legacy zz drop-ins if present
rm -f /etc/taler-exchange/conf.d/zz-hacktivism.conf \
      /etc/taler-exchange/conf.d/zz-hacktivism-coins.conf 2>/dev/null || true

cat >"$OV" <<EOF
# Manual site overrides for exchange.hacktivism.ch (GOA exploration currency).
# Same role as /etc/taler-merchant/merchant-overrides.conf on taler-hacktivism.
# Do not edit overrides.conf (tooling). Do not edit package conf.d defaults.
# No conf.d/zz-* drop-ins.

[exchange]
CURRENCY = GOA
CURRENCY_ROUND_UNIT = GOA:0.00000001
TINY_AMOUNT = GOA:0.00000001
DEFAULT_P2P_EXPIRATION = 14 days
BASE_URL = https://exchange.hacktivism.ch/
SERVE = tcp
PORT = 9011
MASTER_PUBLIC_KEY = ${MASTER_PUB}
# ATTRIBUTE_ENCRYPTION_KEY via @inline-secret@ (see secrets/)
@inline-secret@ exchange-attribute-encryption ../secrets/exchange-attribute-encryption.secret.conf

[currency-goa]
ENABLED = YES
name = "GOA exploration currency"
code = GOA
# SI display units. taler-exchange rejects scale keys outside [-8, 24] (no Ronna/Quetta).
fractional_input_digits = 8
fractional_normal_digits = 0
fractional_trailing_zero_digits = 0
alt_unit_names_are_symbols = NO
alt_unit_names = {"24":"Yotta-GOA","21":"Zetta-GOA","18":"Exa-GOA","15":"Peta-GOA","12":"Tera-GOA","9":"Giga-GOA","6":"Mega-GOA","3":"Kilo-GOA","0":"GOA","-1":"Deci-GOA","-2":"Centi-GOA","-3":"Milli-GOA","-6":"Micro-GOA","-7":"Deci-Micro-GOA","-8":"Atomic-GOA"}
common_amounts = "GOA:10 GOA:20 GOA:50 GOA:100 GOA:200 GOA:1000"

### Disable package demonstrator currencies (like merchant-overrides)
[currency-kudos]
ENABLED = NO

[currency-testkudos]
ENABLED = NO
EOF
echo "Wrote $OV"
grep -E '^(name|code|PORT|CURRENCY|alt_unit|fractional_input|common_)' "$OV" || true

echo "=== 4. GOA coin denominations (1–2–5 ladder) ==="
if [ -f "$COINS" ] && ! grep -q 'VALUE = GOA' "$COINS" 2>/dev/null; then
  mv "$COINS" "${COINS}.package-kudos"
  echo "Moved package coins -> ${COINS}.package-kudos"
fi

cat >"$COINS" << 'COINS_EOF'
# GOA denominations for exchange.hacktivism.ch
# Units: 1 GOA = 1000 mGOA = 1_000_000 uGOA
# VALUE uses base currency; coin sections cover 1–2–5 ladders at u/m/whole scale.

# --- uGOA (10^-6 GOA) ---
[coin_goa_0_000001]
VALUE = GOA:0.000001
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_000002]
VALUE = GOA:0.000002
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_000005]
VALUE = GOA:0.000005
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_00001]
VALUE = GOA:0.00001
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_00002]
VALUE = GOA:0.00002
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_00005]
VALUE = GOA:0.00005
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_0001]
VALUE = GOA:0.0001
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_0002]
VALUE = GOA:0.0002
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_0005]
VALUE = GOA:0.0005
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

# --- mGOA (10^-3 GOA) ---
[coin_goa_0_001]
VALUE = GOA:0.001
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_002]
VALUE = GOA:0.002
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_005]
VALUE = GOA:0.005
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_01]
VALUE = GOA:0.01
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_02]
VALUE = GOA:0.02
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_05]
VALUE = GOA:0.05
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_1]
VALUE = GOA:0.1
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_2]
VALUE = GOA:0.2
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_0_5]
VALUE = GOA:0.5
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

# --- whole GOA ---
[coin_goa_1_0]
VALUE = GOA:1
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_2_0]
VALUE = GOA:2
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_5_0]
VALUE = GOA:5
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_10_0]
VALUE = GOA:10
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_20_0]
VALUE = GOA:20
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_50_0]
VALUE = GOA:50
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_100_0]
VALUE = GOA:100
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_200_0]
VALUE = GOA:200
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA

[coin_goa_1000_0]
VALUE = GOA:1000
DURATION_WITHDRAW = 7 days
DURATION_SPEND = 2 years
DURATION_LEGAL = 3 years
FEE_WITHDRAW = GOA:0
FEE_DEPOSIT = GOA:0
FEE_REFRESH = GOA:0
FEE_REFUND = GOA:0
RSA_KEYSIZE = 2048
CIPHER = RSA
COINS_EOF

echo "Wrote $COINS ($(grep -c '^\[coin_' "$COINS") coin sections)"

echo "=== 5. database ==="
taler-exchange-dbconfig 2>&1 || true
runuser -u taler-exchange-httpd -- taler-exchange-dbinit -c "$CONF" 2>&1 || true

echo "=== 6. next steps (manual) ==="
echo "  - /root/start_base_services_for_taler_exchange.sh   # root: secmods + shell as httpd"
echo "  - ./start_exchange.sh                               # as taler-exchange-httpd"
echo "  - offline: sign denominations + wire accounts for /keys"
echo "  - MASTER_PUBLIC_KEY=$MASTER_PUB"
echo "DONE bootstrap"
