#!/usr/bin/env bash
#
# scripts/check_boundaries.sh
#
# Enforce ADR 0001: Apps-Mode Boundaries and Dependency Rules
#
# Exit codes:
#   0 - all checks passed
#   1 - one or more violations found
#
# Usage:
#   ./scripts/check_boundaries.sh
#
# CI integration: add as a required step before mix compile.

set -u

APPS_DIR="$(cd "$(dirname "$0")/.." && pwd)/apps"
VIOLATIONS=0

red()   { printf '\033[0;31m%s\033[0m\n' "$*"; }
green() { printf '\033[0;32m%s\033[0m\n' "$*"; }
yellow(){ printf '\033[0;33m%s\033[0m\n' "$*"; }

fail() {
  red "  [VIOLATION] $*"
  VIOLATIONS=$((VIOLATIONS + 1))
}

pass() {
  green "  [OK] $*"
}

info() {
  yellow "  [CHECK] $*"
}

echo "========================================"
echo "  Wallet App Boundary Checker (ADR 0001)"
echo "========================================"
echo ""

# -------------------------------------------------------
# RULE 1: wallet_shared_kernel must have NO in_umbrella deps
# -------------------------------------------------------
echo "--- Rule 1: wallet_shared_kernel has no in_umbrella dependencies"
KERNEL_MIX="$APPS_DIR/wallet_shared_kernel/mix.exs"
if [ -f "$KERNEL_MIX" ]; then
  if grep -q "in_umbrella: true" "$KERNEL_MIX"; then
    fail "wallet_shared_kernel/mix.exs contains in_umbrella dependencies (forbidden by ADR 0001)"
  else
    pass "wallet_shared_kernel has no in_umbrella dependencies"
  fi
else
  fail "wallet_shared_kernel/mix.exs not found"
fi

# -------------------------------------------------------
# RULE 2: wallet_web must NOT depend on financial domain apps directly
# (These will only be allowed via service/behaviour interfaces, not DB schemas)
# wallet_web may depend on: shared_kernel, api_contracts, observability, auth, accounts, etc.
# wallet_web MUST NOT depend on: wallet_ledger, wallet_transfers (these come via service modules)
# Note: as domain apps are added in later phases, update this list.
# -------------------------------------------------------
echo ""
echo "--- Rule 2: wallet_web does not import forbidden domain DB schemas"
WEB_LIB="$APPS_DIR/wallet_web/lib"
FORBIDDEN_DB_PATTERNS=(
  "WalletLedger\.Repo"
  "WalletAccounts\.Repo"
  "WalletTransfers\.Repo"
  "WalletSettlement\.Repo"
  "WalletCompliance\.Repo"
)
for pattern in "${FORBIDDEN_DB_PATTERNS[@]}"; do
  if grep -rq "$pattern" "$WEB_LIB" 2>/dev/null; then
    fail "wallet_web/lib contains forbidden direct DB reference: $pattern"
  else
    pass "wallet_web does not reference $pattern directly"
  fi
done

# -------------------------------------------------------
# RULE 3: No circular dependencies (basic check)
# wallet_shared_kernel must not depend on any wallet_* app
# wallet_api_contracts must not depend on wallet_web
# wallet_events must not depend on wallet_web
# wallet_state must not depend on wallet_web
# wallet_observability must not depend on wallet_web
# -------------------------------------------------------
echo ""
echo "--- Rule 3: No forbidden dependency direction violations"

check_no_dep() {
  local app="$1"
  local forbidden_dep="$2"
  local mix_file="$APPS_DIR/$app/mix.exs"
  if [ -f "$mix_file" ]; then
    if grep -q ":$forbidden_dep" "$mix_file"; then
      fail "$app/mix.exs depends on :$forbidden_dep (forbidden - would create circular or upward dependency)"
    else
      pass "$app does not depend on :$forbidden_dep"
    fi
  fi
}

# Foundational apps must not depend on wallet_web (upward dependency)
check_no_dep "wallet_shared_kernel" "wallet_web"
check_no_dep "wallet_api_contracts" "wallet_web"
check_no_dep "wallet_events"        "wallet_web"
check_no_dep "wallet_state"         "wallet_web"
check_no_dep "wallet_observability" "wallet_web"

# wallet_shared_kernel is dependency-free
check_no_dep "wallet_shared_kernel" "wallet_api_contracts"
check_no_dep "wallet_shared_kernel" "wallet_events"
check_no_dep "wallet_shared_kernel" "wallet_state"
check_no_dep "wallet_shared_kernel" "wallet_observability"

# -------------------------------------------------------
# RULE 4: wallet_web must NOT implement financial domain logic
# Check for forbidden Ecto schema definitions in wallet_web that belong to domain apps
# -------------------------------------------------------
echo ""
echo "--- Rule 4: wallet_web does not define financial domain schemas"
FORBIDDEN_SCHEMA_PATTERNS=(
  "use Ecto.Schema"
)
for pattern in "${FORBIDDEN_SCHEMA_PATTERNS[@]}"; do
  # Allow only in shared/support files, not in main lib
  count=$(grep -r "$pattern" "$WEB_LIB" 2>/dev/null | wc -l | tr -d ' ')
  if [ "${count:-0}" -gt "0" ]; then
    info "wallet_web/lib contains $count Ecto.Schema definition(s) - review that these are not financial domain schemas"
    # Not a hard fail for Phase 1 (repo schema is allowed in wallet_web during migration)
  else
    pass "wallet_web has no Ecto.Schema definitions (schemas belong in domain apps)"
  fi
done

# -------------------------------------------------------
# RULE 5: All apps must have a README.md (boundary documentation)
# -------------------------------------------------------
echo ""
echo "--- Rule 5: All OTP apps have boundary documentation (README.md)"
for app_dir in "$APPS_DIR"/*/; do
  app_name=$(basename "$app_dir")
  if [ -f "$app_dir/README.md" ]; then
    pass "$app_name has README.md"
  else
    fail "$app_name is missing README.md (required by ADR 0001 Track B)"
  fi
done

# -------------------------------------------------------
# RULE 6: All apps must have a mix.exs
# -------------------------------------------------------
echo ""
echo "--- Rule 6: All OTP apps have mix.exs"
for app_dir in "$APPS_DIR"/*/; do
  app_name=$(basename "$app_dir")
  if [ -f "$app_dir/mix.exs" ]; then
    pass "$app_name has mix.exs"
  else
    fail "$app_name is missing mix.exs"
  fi
done

# -------------------------------------------------------
# RULE 7: Old module names must not appear in apps/
# (Guard against stale DaProductApp references post-migration)
# -------------------------------------------------------
echo ""
echo "--- Rule 7: No legacy module names in apps/ directory"
LEGACY_PATTERNS=("DaProductApp" "da_product_app")
for pattern in "${LEGACY_PATTERNS[@]}"; do
  count=$(grep -r "$pattern" "$APPS_DIR" 2>/dev/null | wc -l || echo 0)
  if [ "$count" -gt "0" ]; then
    fail "Found $count occurrence(s) of legacy name '$pattern' in apps/ - run migration rename"
    grep -rn "$pattern" "$APPS_DIR" 2>/dev/null | head -10 || true
  else
    pass "No legacy '$pattern' references in apps/"
  fi
done

# -------------------------------------------------------
# Summary
# -------------------------------------------------------
echo ""
echo "========================================"
if [ "$VIOLATIONS" -eq 0 ]; then
  green "  All boundary checks passed (0 violations)"
  echo "========================================"
  exit 0
else
  red "  $VIOLATIONS violation(s) found - see above"
  echo "========================================"
  exit 1
fi
