#!/usr/bin/env bash
set -euo pipefail

BASE_URL="${LEARNITIVE_SEO_BASE_URL:-https://www.learnitive.com}"
BASE_URL="${BASE_URL%/}"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "${TMP_DIR}"' EXIT

log(){ printf '[Learnitive SEO] %s\n' "$*"; }
fail(){ printf '[Learnitive SEO] FAIL: %s\n' "$*" >&2; exit 1; }
request(){
  local path="$1" headers="$2" body="$3"
  curl --silent --show-error --location --max-time 25 --user-agent 'LearnitiveProductionSeoVerifier/2.0' \
    --dump-header "${headers}" --output "${body}" "${BASE_URL}${path}"
}
status_from_headers(){ awk '/^HTTP\// {code=$2} END{print code}' "$1"; }

assert_no_old_brand(){
  local file="$1" label="$2"
  if grep -Eiq 'INTERACTIVE[[:space:]_-]+SHELL|INTERACTIVESHELL|interactive-shell|@interactiveshell|INTERACTIVE_SHELL_' "${file}"; then
    fail "${label} contains obsolete Interactive Shell branding/namespace"
  fi
}

verify_html(){
  local path="$1" slug="$2" marker="${3:-}"
  local headers="${TMP_DIR}/${slug}.headers" body="${TMP_DIR}/${slug}.html"
  request "${path}" "${headers}" "${body}"
  [[ "$(status_from_headers "${headers}")" == '200' ]] || fail "${path} did not return 200"
  grep -Eiq '^content-type:[[:space:]]*text/html' "${headers}" || fail "${path} is not HTML"
  grep -Eiq '<title>[^<]+' "${body}" || fail "${path} has no title"
  grep -Eiq '<meta[^>]+name="description"' "${body}" || fail "${path} has no description"
  grep -Eiq '<link[^>]+rel="canonical"[^>]+href="https://www\.learnitive\.com/' "${body}" || fail "${path} canonical is not the Learnitive www origin"
  grep -Eiq '<meta[^>]+property="og:title"' "${body}" || fail "${path} has no OpenGraph title"
  grep -Eiq '<h1([[:space:]>])' "${body}" || fail "${path} initial HTML has no H1"
  if grep -Eiq '<meta[^>]+name="robots"[^>]+content="[^"]*noindex' "${body}"; then fail "${path} is unexpectedly noindex"; fi
  [[ -z "${marker}" ]] || grep -Fq "${marker}" "${body}" || fail "${path} is missing ${marker}"
  assert_no_old_brand "${body}" "${path}"
  log "PASS HTML ${path}"
}

verify_not_found(){
  local path="$1" slug="$2"
  local headers="${TMP_DIR}/${slug}.headers" body="${TMP_DIR}/${slug}.html"
  request "${path}" "${headers}" "${body}"
  [[ "$(status_from_headers "${headers}")" == '404' ]] || fail "${path} expected 404"
  grep -Eiq 'noindex' "${body}" || fail "${path} 404 is missing noindex"
  assert_no_old_brand "${body}" "${path}"
  log "PASS hidden ${path}"
}

verify_redirect(){
  local path="$1" expected="$2" slug="$3"
  local headers="${TMP_DIR}/${slug}.headers"
  curl --silent --show-error --max-time 20 --head --user-agent 'LearnitiveProductionSeoVerifier/2.0' "${BASE_URL}${path}" > "${headers}"
  local status location
  status="$(awk 'NR==1 {print $2}' "${headers}")"
  [[ "${status}" == '301' ]] || fail "${path} expected 301, got ${status:-unknown}"
  location="$(tr -d '\r' < "${headers}" | awk 'BEGIN{IGNORECASE=1} /^Location:/ {sub(/^[^:]+:[[:space:]]*/,""); print; exit}')"
  [[ "${location}" == "${BASE_URL}${expected}" || "${location}" == "https://www.learnitive.com${expected}" ]] || fail "${path} redirects to ${location:-missing}, expected ${expected}"
  log "PASS redirect ${path} -> ${expected}"
}

verify_gone(){
  local path="$1" slug="$2"
  local headers="${TMP_DIR}/${slug}.headers" body="${TMP_DIR}/${slug}.html"
  request "${path}" "${headers}" "${body}"
  [[ "$(status_from_headers "${headers}")" == '410' ]] || fail "${path} expected 410"
  grep -Eiq 'noindex' "${body}" || fail "${path} 410 is missing noindex"
  log "PASS retired ${path}"
}

verify_binary_asset(){
  local path="$1" type_regex="$2" signature="$3" slug="$4"
  local headers="${TMP_DIR}/${slug}.headers" body="${TMP_DIR}/${slug}.body"
  request "${path}" "${headers}" "${body}"
  grep -Eiq "^content-type:[[:space:]]*${type_regex}" "${headers}" || fail "${path} has wrong Content-Type"
  case "${signature}" in
    ico) [[ "$(od -An -tx1 -N4 "${body}" | tr -d ' \n')" == '00000100' ]] || fail "${path} is not an ICO" ;;
    png) [[ "$(od -An -tx1 -N8 "${body}" | tr -d ' \n')" == '89504e470d0a1a0a' ]] || fail "${path} is not a PNG" ;;
    svg) grep -Eiq '<svg([[:space:]>])' "${body}" || fail "${path} is not SVG" ;;
  esac
  log "PASS asset ${path}"
}

for item in \
  '/ home' \
  '/features features' \
  '/use-cases use-cases' \
  '/tools tools' \
  '/pricing pricing' \
  '/blog blog' \
  '/docs docs' \
  '/learn learn' \
  '/about about' \
  '/faq faq'; do
  verify_html "${item% *}" "${item#* }"
done

for item in \
  '/compare hidden-compare' \
  '/migrate hidden-migrate' \
  '/software-list hidden-software-list' \
  '/use-cases/software-development hidden-software-development'; do
  verify_not_found "${item% *}" "${item#* }"
done

while IFS=$'\t' read -r source target; do
  [[ -n "${source}" ]] || continue
  slug="redirect-$(printf '%s' "${source}" | tr -cs '[:alnum:]' '-')"
  verify_redirect "${source}" "${target}" "${slug}"
done < <(node --input-type=module - <<'NODE'
import { PUBLIC_LEGACY_REDIRECTS, PUBLIC_LEGACY_BLOG_REDIRECTS } from './server/public-legacy-redirects.mjs';
for (const registry of [PUBLIC_LEGACY_REDIRECTS, PUBLIC_LEGACY_BLOG_REDIRECTS]) for (const [source,target] of Object.entries(registry)) console.log(`${source}\t${target}`);
NODE
)

while IFS= read -r source; do
  [[ -n "${source}" ]] || continue
  slug="gone-$(printf '%s' "${source}" | tr -cs '[:alnum:]' '-')"
  verify_gone "${source}" "${slug}"
done < <(node --input-type=module - <<'NODE'
import { PUBLIC_LEGACY_GONE } from './server/public-legacy-redirects.mjs';
for (const source of PUBLIC_LEGACY_GONE) console.log(source);
NODE
)

verify_binary_asset '/favicon.ico' 'image/(x-icon|vnd\.microsoft\.icon)' ico favicon-ico
verify_binary_asset '/favicon-96x96.png' 'image/png' png favicon-png
verify_binary_asset '/favicon.svg' 'image/svg\+xml' svg favicon-svg

request '/sitemap.xml' "${TMP_DIR}/sitemap.headers" "${TMP_DIR}/sitemap.xml"
grep -Fq '<loc>' "${TMP_DIR}/sitemap.xml" || fail 'sitemap has no URLs'
for forbidden in '/compare' '/migrate' '/software-list' '/use-cases/software-development'; do
  if grep -Fq "${BASE_URL}${forbidden}" "${TMP_DIR}/sitemap.xml"; then fail "sitemap exposes hidden route ${forbidden}"; fi
done
assert_no_old_brand "${TMP_DIR}/sitemap.xml" 'sitemap'

request '/robots.txt' "${TMP_DIR}/robots.headers" "${TMP_DIR}/robots.txt"
grep -Fq 'Sitemap:' "${TMP_DIR}/robots.txt" || fail 'robots.txt has no sitemap declaration'

log "Production public SEO verification passed for ${BASE_URL}."
