#!/bin/bash
# e2e-helpers.sh — Shared validation functions for E2E regression tests
set -euo pipefail

# Counters
PASS=0
FAIL=0
WARN=0
SUITE_NAME=""

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

init_suite() {
  SUITE_NAME="$1"
  PASS=0
  FAIL=0
  WARN=0
  echo -e "${BLUE}═══════════════════════════════════════${NC}"
  echo -e "${BLUE}  E2E Suite: $SUITE_NAME${NC}"
  echo -e "${BLUE}═══════════════════════════════════════${NC}"
  echo ""
}

pass() {
  PASS=$((PASS + 1))
  echo -e "  ${GREEN}PASS${NC} $1"
}

fail() {
  FAIL=$((FAIL + 1))
  echo -e "  ${RED}FAIL${NC} $1"
}

warn() {
  WARN=$((WARN + 1))
  echo -e "  ${YELLOW}WARN${NC} $1"
}

print_summary() {
  local total=$((PASS + FAIL))
  echo ""
  echo -e "${BLUE}───────────────────────────────────────${NC}"
  echo -e "  ${SUITE_NAME}: ${PASS}/${total} PASS, ${FAIL} FAIL, ${WARN} WARN"
  echo -e "${BLUE}───────────────────────────────────────${NC}"
  echo ""
  return $FAIL
}

# --- Assertions ---

assert_has_section() {
  local file="$1"
  local header="$2"
  local description="${3:-Section: $header}"
  if grep -qE "^#{1,4} .*${header}" "$file"; then
    pass "$description"
  else
    fail "$description — header '$header' not found"
  fi
}

assert_min_lines() {
  local file="$1"
  local min="$2"
  local description="${3:-Minimum $min lines}"
  local count
  count=$(wc -l < "$file" | tr -d ' ')
  if [ "$count" -ge "$min" ]; then
    pass "$description ($count lines)"
  else
    fail "$description — only $count lines (min: $min)"
  fi
}

assert_encoding_ok() {
  local file="$1"
  local description="${2:-UTF-8 encoding valid}"
  # Check for common broken UTF-8 sequences
  if file "$file" | grep -qi "utf-8\|ascii\|unicode"; then
    pass "$description"
  else
    fail "$description — encoding not UTF-8/ASCII"
  fi
}

assert_no_ascii_approximation() {
  local file="$1"
  local description="${2:-No ASCII approximation of Norwegian chars}"
  # Check for ae/oe/aa used where æ/ø/å should be (Norwegian words)
  # Only flag common Norwegian words that should have æøå
  local violations=0
  for pattern in '\bvaere\b' '\bfoerste\b' '\bhoey\b' '\bgjoere\b' '\baarlig\b' '\bsaerlig\b' '\bnoedvendig\b'; do
    if grep -qiE "$pattern" "$file" 2>/dev/null; then
      violations=$((violations + 1))
    fi
  done
  if [ "$violations" -eq 0 ]; then
    pass "$description"
  else
    fail "$description — $violations ASCII approximation patterns found"
  fi
}

assert_scores_in_range() {
  local file="$1"
  local description="${2:-Scores in X/5 format within range}"
  # Match X/5 or X.X/5 patterns and verify range
  local bad_scores=0
  while IFS= read -r match; do
    local score="${match%%/*}"
    score=$(echo "$score" | tr -d ' ')
    # Check if it's a valid number between 0 and 5
    if echo "$score" | grep -qE '^[0-5](\.[0-9]+)?$'; then
      :
    else
      bad_scores=$((bad_scores + 1))
    fi
  done < <(grep -oE '[0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || true)

  local total_scores
  total_scores=$(grep -cE '[0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || echo "0")
  if [ "$total_scores" -gt 0 ] && [ "$bad_scores" -eq 0 ]; then
    pass "$description ($total_scores scores found)"
  elif [ "$total_scores" -eq 0 ]; then
    fail "$description — no X/5 scores found"
  else
    fail "$description — $bad_scores out-of-range scores"
  fi
}

assert_has_nok_amounts() {
  local file="$1"
  local min="${2:-1}"
  local description="${3:-NOK amounts present}"
  local count
  count=$(grep -cE '([0-9]+[.,]?[0-9]*(M|K)\s*NOK|[0-9]+\s*NOK|NOK\s*[0-9]+|[0-9]+\s*000\s*NOK)' "$file" 2>/dev/null || echo "0")
  if [ "$count" -ge "$min" ]; then
    pass "$description ($count found)"
  else
    fail "$description — only $count NOK amounts (min: $min)"
  fi
}

assert_min_tables() {
  local file="$1"
  local min="$2"
  local description="${3:-Minimum $min markdown tables}"
  # Count lines starting with | that contain | somewhere after the first char (table rows)
  local table_separators
  table_separators=$(grep -cE '^\|.*\|.*\|' "$file" 2>/dev/null || echo "0")
  # Rough estimate: each table has header + separator + at least 1 row = 3 lines minimum
  local estimated_tables=$((table_separators / 3))
  if [ "$estimated_tables" -ge "$min" ]; then
    pass "$description (~$estimated_tables tables)"
  else
    fail "$description — only ~$estimated_tables tables (min: $min)"
  fi
}

assert_matches_pattern() {
  local file="$1"
  local pattern="$2"
  local description="${3:-Pattern match: $pattern}"
  if grep -qE "$pattern" "$file"; then
    pass "$description"
  else
    fail "$description"
  fi
}

assert_has_dimensions() {
  local file="$1"
  local min="$2"
  local description="${3:-Minimum $min security dimensions}"
  local count
  count=$(grep -cE '^\| .+ \| [0-9]+\.?[0-9]*/5' "$file" 2>/dev/null || echo "0")
  if [ "$count" -ge "$min" ]; then
    pass "$description ($count dimensions)"
  else
    fail "$description — only $count dimensions (min: $min)"
  fi
}
