#!/usr/bin/env bash
# Build / refresh OSRM routing graph для site-finder (#39).
#
# Готовит .osrm-файлы (MLD pipeline) из OpenStreetMap-экстракта Свердловской
# области и кладёт их в ./data/osrm/, откуда их монтирует docker-compose.prod.yml
# (service `osrm`, volume ./data/osrm:/data → osrm-routed читает /data/<region>.osrm).
#
# === Где запускать ===
#   На VPS из /opt/gendesign:  bash scripts/build_osrm.sh
#   (требует docker + ~5GB свободного диска + ~3GB свободной RAM на время extract).
#
# === ВАЖНО: это offline-задача, НЕ часть deploy.yml ===
#   Download ~600MB-1.5GB + build 30-50 мин. Запускается ВРУЧНУЮ оркестратором,
#   НЕ на каждом push. deploy.yml только поднимает уже готовый osrm-контейнер.
#
# === Idempotent / re-runnable ===
#   Повторный запуск перекачивает свежий pbf и пересобирает граф (overwrite).
#   Безопасно гонять ежемесячно (osm.pbf на Geofabrik обновляется ежедневно).
#   # monthly refresh: cron на VPS, напр.  0 4 1 * * bash /opt/gendesign/scripts/build_osrm.sh >> /var/log/osrm-build.log 2>&1
#   После refresh: docker compose -p gendesign -f docker-compose.prod.yml up -d --force-recreate --no-deps osrm
#
# === Регион / источник pbf ===
#   Geofabrik НЕ публикует Свердловскую область отдельным extract'ом — только
#   «Уральский ФО» (ural-fed-district). Два режима (CLIP=1 по умолчанию):
#
#   CLIP=1 (default, РЕКОМЕНДОВАНО): качаем Ural-FO pbf и обрезаем по bbox
#          Свердл. обл. через `osmium extract`. Результат легче → меньше RAM/диск
#          в build и в runtime (osrm-routed warm ~0.8-1.2GB вместо ~1.5GB+ на
#          весь Ural-FO). Минус: нужен extra-шаг osmium (запускаем в docker).
#
#   CLIP=0: используем весь Ural-FO pbf как есть (zero-clip, проще, но тяжелее —
#          граф Курган/Тюмень/ХМАО/ЯНАО грузится в RAM без пользы для Свердл).
#          Бери, если RAM не жмёт и нужен запас на соседние регионы.
#
#   bbox Свердловской обл (грубый, с запасом): lon 57.2..66.2, lat 56.0..62.0.
#   Можно сузить до ЕКБ-агломерации если RAM критична (lon 59.0..62.5, lat 56.2..58.2)
#   через EKB_TIGHT=1.
#
# === Профили ===
#   Car (driving) — основной, строится всегда → <region>.osrm*.
#   Foot (walking) — опциональный Phase-2, строится при WALK=1 → <region>-foot.osrm*.
#   Для walking нужен второй compose-service (osrm-walk) — см. docs/osrm-routing.md.
#   Этот PR car-first; walk выключен по умолчанию (issue хочет оба eventually).
#
# === Проверка после build ===
#   docker compose -p gendesign -f docker-compose.prod.yml up -d osrm
#   docker compose -p gendesign -f docker-compose.prod.yml exec osrm \
#     sh -c 'echo OK'   # контейнер жив
#   # route-probe С ХОСТА (внутри образа нет curl) — временно прокинуть порт:
#   docker run --rm --network gendesign_default curlimages/curl:8 -fsS \
#     'http://osrm:5000/route/v1/driving/60.6,56.84;60.65,56.86'
#   ↑ ожидаем JSON {"code":"Ok","routes":[...]}.

set -euo pipefail

# --- Config (override через env) -------------------------------------------
OSRM_IMAGE="${OSRM_IMAGE:-osrm/osrm-backend:latest}"
OSMIUM_IMAGE="${OSMIUM_IMAGE:-stefda/osmium-tool:latest}"
REGION="${OSRM_REGION:-sverdlovsk}"           # имя выходных .osrm* (= OSRM_REGION в compose)
PBF_URL="${PBF_URL:-https://download.geofabrik.de/russia/ural-fed-district-latest.osm.pbf}"
CLIP="${CLIP:-1}"                             # 1 = обрезать по bbox Свердл, 0 = весь Ural-FO
EKB_TIGHT="${EKB_TIGHT:-0}"                   # 1 = узкий bbox только ЕКБ-агломерация
WALK="${WALK:-0}"                             # 1 = ещё и пеший профиль <region>-foot.osrm*
CAR="${CAR:-1}"                               # 0 = пропустить car-граф (foot-only refresh, #39 A3)
CAR_PROFILE="${CAR_PROFILE:-/opt/car.lua}"    # встроенные профили в osrm-backend образе
FOOT_PROFILE="${FOOT_PROFILE:-/opt/foot.lua}"

# bbox: left,bottom,right,top  (lon_min,lat_min,lon_max,lat_max)
if [ "$EKB_TIGHT" = "1" ]; then
    BBOX="${BBOX:-59.0,56.2,62.5,58.2}"       # ЕКБ-агломерация (минимум RAM)
else
    BBOX="${BBOX:-57.2,56.0,66.2,62.0}"       # вся Свердловская обл (с запасом)
fi

# Каталог host (= ./data/osrm в compose). Скрипт зовём из /opt/gendesign.
DATA_DIR="${DATA_DIR:-$(pwd)/data/osrm}"
mkdir -p "$DATA_DIR"

RAW_PBF="$DATA_DIR/${REGION}-raw.osm.pbf"     # сырой Ural-FO (или clip-источник)
WORK_PBF="$DATA_DIR/${REGION}.osm.pbf"        # то, что реально пойдёт в osrm-extract

echo "=== OSRM build ==="
echo "  region          : $REGION"
echo "  pbf source      : $PBF_URL"
echo "  clip to bbox    : CLIP=$CLIP  BBOX=$BBOX  (EKB_TIGHT=$EKB_TIGHT)"
echo "  walking profile : WALK=$WALK"
echo "  data dir (host) : $DATA_DIR"
echo ""

# --- 1. Download ------------------------------------------------------------
# -N: качаем только если на сервере новее (idempotent monthly refresh).
echo "=== 1. Download pbf (Ural-FO ≈600MB) ==="
if command -v wget >/dev/null 2>&1; then
    wget -N -O "$RAW_PBF" "$PBF_URL"
else
    curl -fSL --time-cond "$RAW_PBF" -o "$RAW_PBF" "$PBF_URL"
fi

# --- 2. Clip (optional) -----------------------------------------------------
if [ "$CLIP" = "1" ]; then
    echo "=== 2. Clip to Свердл bbox через osmium ($BBOX) ==="
    docker run --rm -v "$DATA_DIR:/data" "$OSMIUM_IMAGE" \
        osmium extract -b "$BBOX" "/data/$(basename "$RAW_PBF")" \
        -o "/data/$(basename "$WORK_PBF")" --overwrite
else
    echo "=== 2. No clip (CLIP=0) — используем Ural-FO целиком ==="
    cp -f "$RAW_PBF" "$WORK_PBF"
fi

# --- helper: запуск osrm-backend образа на /data --------------------------
osrm() {
    docker run --rm -v "$DATA_DIR:/data" "$OSRM_IMAGE" "$@"
}

# --- 3. MLD pipeline (car) --------------------------------------------------
# MLD = extract → partition → customize. НЕ osrm-contract (то CH-алгоритм,
# несовместим с --algorithm mld в compose).
#
# osrm-extract пишет <pbf-без-.osm.pbf>.osrm. Имя входного pbf специально равно
# целевому базовому имени (<region>.osm.pbf → <region>.osrm; <region>-foot.osm.pbf
# → <region>-foot.osrm), поэтому partition/customize работают по тому же базовому
# имени и переименование не требуется.
build_profile() {
    local profile="$1" src_pbf="$2"
    local base extracted
    base="$(basename "${src_pbf%.osm.pbf}")"
    extracted="/data/${base}.osrm"
    echo "--- extract ($profile → ${base}.osrm) ---"
    osrm osrm-extract -p "$profile" "/data/$(basename "$src_pbf")"
    echo "--- partition (${base}.osrm) ---"
    osrm osrm-partition "$extracted"
    echo "--- customize (${base}.osrm) ---"
    osrm osrm-customize "$extracted"
}

if [ "$CAR" = "1" ]; then
    echo "=== 3. Build car profile → ${REGION}.osrm* ==="
    build_profile "$CAR_PROFILE" "$WORK_PBF"
else
    echo "=== 3. Skip car profile (CAR=0) — foot-only refresh, не трогаем живой ${REGION}.osrm ==="
fi

# --- 4. MLD pipeline (foot, optional) --------------------------------------
if [ "$WALK" = "1" ]; then
    echo "=== 4. Build foot profile → ${REGION}-foot.osrm* ==="
    # Отдельная копия pbf под пеший граф (osrm-extract overwrite'ит базу).
    WALK_PBF="$DATA_DIR/${REGION}-foot.osm.pbf"
    cp -f "$WORK_PBF" "$WALK_PBF"
    build_profile "$FOOT_PROFILE" "$WALK_PBF"
else
    echo "=== 4. Skip foot profile (WALK=0) — car-first, см. docs/osrm-routing.md ==="
fi

# --- 5. Cleanup heavy intermediates ----------------------------------------
echo "=== 5. Cleanup промежуточных .pbf (граф .osrm* уже собран) ==="
rm -f "$RAW_PBF" "$WORK_PBF" "${DATA_DIR}/${REGION}-foot.osm.pbf" 2>/dev/null || true

echo ""
echo "=== DONE ==="
echo "Артефакты в $DATA_DIR:"
ls -lh "$DATA_DIR"/*.osrm* 2>/dev/null | awk '{print "  "$5"\t"$9}' || true
echo ""
echo "Дальше:"
echo "  docker compose -p gendesign -f docker-compose.prod.yml up -d osrm"
echo "  # verify (curl с хоста — внутри образа curl нет):"
echo "  docker run --rm --network gendesign_default curlimages/curl:8 -fsS \\"
echo "    'http://osrm:5000/route/v1/driving/60.6,56.84;60.65,56.86'"
