#!/bin/bash
# Post-deploy smoketest for josie.health services

set -euo pipefail

API_URL="${API_URL:-https://api.josie.health}"
WEB_URL="${WEB_URL:-https://josie.health}"
HEARTBEAT_URL="${HEARTBEAT_URL:-https://heartbeat.josie.health}"
API_AUTH="${API_AUTH:-}"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
NC='\033[0m'

TESTS_PASSED=0
TESTS_FAILED=0

check_status() {
    local description="$1"
    local url="$2"
    local expected_status="$3"
    local auth="${4:-}"

    local curl_args=(--connect-timeout 5 -s -o /dev/null -w '%{http_code}')
    if [ -n "$auth" ]; then
        curl_args+=(-u "$auth")
    fi

    local status
    status=$(curl "${curl_args[@]}" "$url") || status="000"

    if [ "$status" = "$expected_status" ]; then
        echo -e "${GREEN}PASS${NC}: $description (HTTP $status)"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    else
        echo -e "${RED}FAIL${NC}: $description"
        echo "       Expected HTTP $expected_status, got $status"
        TESTS_FAILED=$((TESTS_FAILED + 1))
    fi
}

check_header() {
    local description="$1"
    local url="$2"
    local header_name="$3"
    local expected_value="${4:-}"

    local headers
    headers=$(curl --connect-timeout 5 -s -D - -o /dev/null "$url") || headers=""

    local header_line
    header_line=$(echo "$headers" | grep -i "^${header_name}:" || true)

    if [ -z "$header_line" ]; then
        echo -e "${RED}FAIL${NC}: $description"
        echo "       Header '$header_name' not found"
        TESTS_FAILED=$((TESTS_FAILED + 1))
        return
    fi

    if [ -n "$expected_value" ]; then
        local actual_value
        actual_value=$(echo "$header_line" | sed "s/^[^:]*: *//" | tr -d '\r')
        if [ "$actual_value" = "$expected_value" ]; then
            echo -e "${GREEN}PASS${NC}: $description ($actual_value)"
            TESTS_PASSED=$((TESTS_PASSED + 1))
        else
            echo -e "${RED}FAIL${NC}: $description"
            echo "       Expected '$expected_value', got '$actual_value'"
            TESTS_FAILED=$((TESTS_FAILED + 1))
        fi
    else
        echo -e "${GREEN}PASS${NC}: $description"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    fi
}

check_header_absent() {
    local description="$1"
    local url="$2"
    local header_name="$3"
    local extra_args=("${@:4}")

    local headers
    headers=$(curl --connect-timeout 5 -s -D - -o /dev/null "${extra_args[@]}" "$url") || headers=""

    local header_line
    header_line=$(echo "$headers" | grep -i "^${header_name}:" || true)

    if [ -z "$header_line" ]; then
        echo -e "${GREEN}PASS${NC}: $description"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    else
        echo -e "${RED}FAIL${NC}: $description"
        echo "       Header '$header_name' unexpectedly present: $(echo "$header_line" | tr -d '\r')"
        TESTS_FAILED=$((TESTS_FAILED + 1))
    fi
}

check_json() {
    local description="$1"
    local url="$2"
    local jq_expr="$3"
    local auth="${4:-}"

    local curl_args=(--connect-timeout 5 -s)
    if [ -n "$auth" ]; then
        curl_args+=(-u "$auth")
    fi

    local response
    response=$(curl "${curl_args[@]}" "$url") || response=""

    local result
    result=$(echo "$response" | jq -e "$jq_expr" 2>/dev/null) || result=""

    if [ -n "$result" ] && [ "$result" != "false" ] && [ "$result" != "null" ]; then
        echo -e "${GREEN}PASS${NC}: $description"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    else
        echo -e "${RED}FAIL${NC}: $description"
        echo "       jq '$jq_expr' failed on response"
        echo "       Response: $(echo "$response" | head -c 200)"
        TESTS_FAILED=$((TESTS_FAILED + 1))
    fi
}

echo ""
echo -e "${BOLD}Post-deploy smoketest${NC}"
echo "API:       $API_URL"
echo "Web:       $WEB_URL"
echo "Heartbeat: $HEARTBEAT_URL"
echo ""

# -- Service Availability --
echo -e "${BOLD}Service Availability${NC}"
echo "---"

check_json "API health endpoint returns ok with redis connected" \
    "$API_URL/health" \
    '.status == "ok" and .redis_connection == "connected"'

check_status "Web frontend returns 302" \
    "$WEB_URL" 302

check_status "Heartbeat returns 200" \
    "$HEARTBEAT_URL" 200

check_status "Public /v1/substances returns 200" \
    "$API_URL/v1/substances" 200

check_status "API docs at /v1/ return 200" \
    "$API_URL/v1/" 200

echo ""

# -- Authentication Enforcement --
echo -e "${BOLD}Authentication Enforcement${NC}"
echo "---"

check_status "Protected endpoint returns 401 without credentials" \
    "$API_URL/v1/metrics/substances" 401

if [ -n "$API_AUTH" ]; then
    check_status "Protected endpoint returns 200 with valid auth" \
        "$API_URL/v1/metrics/substances" 200 "$API_AUTH"

    check_status "Protected endpoint returns 401 with wrong password" \
        "$API_URL/v1/metrics/substances" 401 "admin:wrong_password_definitely"
else
    echo -e "${YELLOW}SKIP${NC}: Auth tests require API_AUTH env var"
    echo -e "${YELLOW}SKIP${NC}: Auth tests require API_AUTH env var"
fi

echo ""

# -- Security Headers --
echo -e "${BOLD}Security Headers${NC}"
echo "---"

check_header "X-Frame-Options is DENY" \
    "$API_URL/health" "X-Frame-Options" "DENY"

check_header "X-Content-Type-Options is nosniff" \
    "$API_URL/health" "X-Content-Type-Options" "nosniff"

check_header "Strict-Transport-Security present" \
    "$API_URL/health" "Strict-Transport-Security"

check_header "Content-Security-Policy present" \
    "$API_URL/health" "Content-Security-Policy"

echo ""

# -- CORS Restrictions --
echo -e "${BOLD}CORS Restrictions${NC}"
echo "---"

cors_headers=$(curl --connect-timeout 5 -s -D - -o /dev/null \
    -H "Origin: https://josie.health" "$API_URL/health") || cors_headers=""
acao=$(echo "$cors_headers" | grep -i "^Access-Control-Allow-Origin:" | sed 's/^[^:]*: *//' | tr -d '\r' || true)
if [ "$acao" = "https://josie.health" ]; then
    echo -e "${GREEN}PASS${NC}: Allowed origin returns ACAO header"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}FAIL${NC}: Allowed origin returns ACAO header"
    echo "       Expected 'https://josie.health', got '$acao'"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

check_header_absent "Disallowed origin gets no ACAO header" \
    "$API_URL/health" "Access-Control-Allow-Origin" \
    -H "Origin: https://evil.com"

echo ""

# -- Data Flow --
echo -e "${BOLD}Data Flow${NC}"
echo "---"

if [ -n "$API_AUTH" ]; then
    check_json "GET /v1/metrics/substances returns data array" \
        "$API_URL/v1/metrics/substances" \
        '.data | type == "array"' "$API_AUTH"
else
    echo -e "${YELLOW}SKIP${NC}: Data flow test requires API_AUTH env var"
fi

check_json "GET /v1/substances/caffeine/info returns substance info" \
    "$API_URL/v1/substances/caffeine/info" \
    '.data.name'

echo ""

# -- Summary --
echo "=================================="
TOTAL=$((TESTS_PASSED + TESTS_FAILED))
echo "Tests completed: $TOTAL total"
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
echo -e "${RED}Failed: $TESTS_FAILED${NC}"

if [ $TESTS_FAILED -gt 0 ]; then
    exit 1
fi
