#!/usr/bin/env sh
set -eu

assert_contains() {
  file="$1"
  pattern="$2"
  if ! grep -Fq "$pattern" "$file"; then
    echo "missing pattern in $file: $pattern" >&2
    exit 1
  fi
}

assert_not_contains() {
  file="$1"
  pattern="$2"
  if grep -Fq "$pattern" "$file"; then
    echo "forbidden pattern in $file: $pattern" >&2
    exit 1
  fi
}

staging_pull=".gitea/workflows/staging_code_pull.yml"
pull_compose="docker/staging_pull_compose.template.yaml"
deploy_compose="deploy/templates/docker-compose.yaml"
deploy_gateway="deploy/templates/gateway/nginx.conf"
userfront_dockerfile="userfront/Dockerfile"
devfront_vite="devfront/vite.config.ts"
orgfront_vite="orgfront/vite.config.ts"
adminfront_vite="adminfront/vite.config.ts"
adminfront_runtime="adminfront/scripts/runtime-mode.sh"
devfront_runtime="devfront/scripts/runtime-mode.sh"
orgfront_runtime="orgfront/scripts/runtime-mode.sh"
adminfront_dockerfile="adminfront/Dockerfile"
devfront_dockerfile="devfront/Dockerfile"
orgfront_dockerfile="orgfront/Dockerfile"

for file in \
  "$staging_pull" \
  "$pull_compose" \
  "$deploy_compose" \
  "$deploy_gateway" \
  "$userfront_dockerfile" \
  "$adminfront_vite" \
  "$devfront_vite" \
  "$orgfront_vite" \
  "$adminfront_runtime" \
  "$devfront_runtime" \
  "$orgfront_runtime" \
  "$adminfront_dockerfile" \
  "$devfront_dockerfile" \
  "$orgfront_dockerfile"
do
  if [ ! -f "$file" ]; then
    echo "missing expected file: $file" >&2
    exit 1
  fi
done

for workflow in "$staging_pull"; do
  assert_contains "$workflow" 'ADMINFRONT_URL=${{ vars.ADMINFRONT_URL }}'
  assert_contains "$workflow" 'DEVFRONT_URL=${{ vars.DEVFRONT_URL }}'
  assert_contains "$workflow" 'ORGFRONT_URL=${{ vars.ORGFRONT_URL }}'
  assert_contains "$workflow" 'KRATOS_ALLOWED_RETURN_URLS_JSON=${{ vars.KRATOS_ALLOWED_RETURN_URLS_JSON }}'
  assert_contains "$workflow" 'KRATOS_ALLOWED_RETURN_URLS_EXTRA=${{ vars.KRATOS_ALLOWED_RETURN_URLS_EXTRA }}'
done

assert_contains "$staging_pull" 'bash scripts/render_ory_config.sh'
assert_contains "$staging_pull" 'chmod -R 777 config/.generated/ory'
assert_contains "$staging_pull" 'docker compose -f staging_pull_compose.yaml build --pull'
assert_contains "$staging_pull" 'docker compose -f staging_pull_compose.yaml up -d --remove-orphans --renew-anon-volumes'
assert_contains "$staging_pull" 'check_container_http baron_gateway 5000'
assert_contains "$staging_pull" 'check_container_http baron_userfront 5000'

assert_contains "$userfront_dockerfile" "FROM ghcr.io/cirruslabs/flutter:3.38.0 AS build"
assert_contains ".dockerignore" "**/build"
assert_contains "$userfront_dockerfile" "RUN rm -rf build/web && flutter build web --release --wasm"
assert_contains "$userfront_dockerfile" "FROM alpine:3.23 AS production"
assert_contains "$userfront_dockerfile" "COPY --from=optimize /work/build/web /usr/share/nginx/html"
assert_contains ".gitea/workflows/code_check.yml" "rm -rf build/web"
assert_contains ".gitea/workflows/userfront_e2e_full_nightly.yml" "rm -rf build/web"
assert_contains "$pull_compose" "baron_devfront"
assert_contains "$pull_compose" "baron_orgfront"
for app in adminfront devfront orgfront; do
  assert_contains "$pull_compose" "$app:"
  assert_contains "$pull_compose" "context: ."
  assert_contains "$pull_compose" "dockerfile: ./$app/Dockerfile"
  assert_contains "$pull_compose" "VITE_OIDC_AUTHORITY: \${VITE_OIDC_AUTHORITY:-}"
  assert_not_contains "$pull_compose" "context: ./$app"
  assert_not_contains "$pull_compose" "./$app:/app"
done
assert_not_contains "$pull_compose" "/app/node_modules"
assert_contains "$pull_compose" "dockerfile: userfront/Dockerfile"
assert_contains "$pull_compose" "target: production"
assert_not_contains "$pull_compose" 'target: ${USERFRONT_BUILD_TARGET:-dev}'
assert_not_contains "$pull_compose" "target: dev"
assert_not_contains "$pull_compose" "flutter run"
assert_contains "$pull_compose" "http://127.0.0.1:5173/"
assert_contains "$pull_compose" "http://127.0.0.1:5175/"
assert_contains "$pull_compose" 'APP_ENV=${APP_ENV:-stage}'

assert_contains "$deploy_compose" "dockerfile: ./adminfront/Dockerfile"
assert_contains "$deploy_compose" "dockerfile: ./devfront/Dockerfile"
assert_contains "$deploy_compose" "dockerfile: ./orgfront/Dockerfile"
assert_contains "$deploy_compose" "dockerfile: ./userfront/Dockerfile"
assert_contains "$deploy_compose" "target: production"
assert_not_contains "$deploy_compose" "sh ./scripts/runtime-mode.sh"
assert_not_contains "$deploy_compose" "command: npm run dev"
assert_not_contains "$deploy_compose" "image: node:20-alpine"
assert_contains "$deploy_gateway" "root /usr/share/nginx/html;"
assert_contains "$deploy_gateway" 'try_files $uri $uri/ /index.html;'
assert_not_contains "$deploy_gateway" "baron_userfront"
assert_not_contains "$deploy_gateway" "userfront_upstream"
assert_not_contains "$deploy_gateway" "proxy_pass http://baron_userfront"

for app in adminfront devfront orgfront; do
  assert_contains ".gitea/workflows/build_RC.yml" "Build and push $app RC image"
  assert_contains ".gitea/workflows/build_RC.yml" "file: ./$app/Dockerfile"
  assert_not_contains ".gitea/workflows/build_RC.yml" "context: ./$app"
done
assert_contains ".gitea/workflows/build_RC.yml" "Build and push userfront RC image"
assert_contains ".gitea/workflows/build_RC.yml" "context: ."
assert_contains ".gitea/workflows/build_RC.yml" "file: ./userfront/Dockerfile"
assert_contains ".gitea/workflows/build_RC.yml" "target: production"
assert_not_contains ".gitea/workflows/build_RC.yml" "context: ./userfront"

for app in adminfront devfront orgfront; do
  dockerfile="$app/Dockerfile"
  assert_contains "$dockerfile" "COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./"
  assert_contains "$dockerfile" "RUN pnpm install --frozen-lockfile --ignore-scripts"
  assert_contains "$dockerfile" "FROM node:24-alpine AS production"
  assert_contains "$dockerfile" "COPY scripts/serve_frontend_prod.mjs ./serve_frontend_prod.mjs"
  assert_contains "$dockerfile" "RUN npm run build"
  assert_contains "$dockerfile" 'CMD ["node", "./serve_frontend_prod.mjs"]'
  assert_not_contains "$dockerfile" "cd common && pnpm install"
  assert_not_contains "$dockerfile" "npm install -g serve"
  assert_not_contains "$dockerfile" "runtime-mode.sh"
done
assert_contains "scripts/serve_frontend_prod.mjs" "pathname === \"/api\" || pathname.startsWith(\"/api/\")"
assert_contains "scripts/serve_frontend_prod.mjs" "API_PROXY_TARGET"

assert_contains "$adminfront_vite" "/tmp/baron-sso-adminfront-dist"
assert_contains "$adminfront_vite" "/tmp/baron-sso-adminfront-vite-cache"
assert_contains "adminfront/biome.json" '".vite"'
assert_contains "adminfront/tsconfig.app.json" '"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]'
assert_contains "$devfront_vite" "/tmp/baron-sso-devfront-dist"
assert_contains "$devfront_vite" "/tmp/baron-sso-devfront-vite-cache"
assert_contains "$devfront_vite" "hostFromUrl(process.env.DEVFRONT_URL)"
assert_contains "$devfront_vite" "process.env.DEVFRONT_ALLOWED_HOSTS"
assert_contains "devfront/biome.json" '".vite"'
assert_contains "devfront/tsconfig.app.json" '"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]'
assert_contains "$orgfront_vite" "/tmp/baron-sso-orgfront-dist"
assert_contains "$orgfront_vite" "/tmp/baron-sso-orgfront-vite-cache"
assert_contains "$orgfront_vite" '"sorg.hmac.kr"'
assert_contains "orgfront/biome.json" '".vite"'
assert_contains "orgfront/tsconfig.app.json" '"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]'

for runtime_script in "$adminfront_runtime" "$devfront_runtime" "$orgfront_runtime"; do
  assert_contains "$runtime_script" "ensure_frontend_dependencies"
  assert_contains "$runtime_script" "package-lock.json"
  assert_contains "$runtime_script" "npm ci"
  assert_contains "$runtime_script" ".baron-deps-hash"
done

echo "staging frontend deploy policy checks passed"
