#!/bin/bash
set -euo pipefail

# Health check script for AW services
# Returns 0 if all services are healthy, 1 otherwise

SERVICES=("activitywatch-server" "aw-worktime-api" "aw-worktime-ui-bridge")
UNHEALTHY_SERVICES=()
WARNINGS=()

if [[ -f /etc/activitywatch/aw-server.env ]]; then
    # shellcheck disable=SC1091
    source /etc/activitywatch/aw-server.env
fi

WORKTIME_HEALTH_BASE="${AW_RUS_HEALTH_WORKTIME_API:-${AW_WORKTIME_REPORT_BASE:-http://127.0.0.1:5610}}"
WORKTIME_HEALTH_URL="${WORKTIME_HEALTH_BASE%/}/health"
WORKTIME_HEALTH_TIMEOUT_SECONDS="${AW_RUS_HEALTH_WORKTIME_TIMEOUT_SECONDS:-15}"
AW_HEALTH_API_TIMEOUT_SECONDS="${AW_RUS_HEALTH_AW_TIMEOUT_SECONDS:-15}"
AW_HEALTH_API_ATTEMPTS="${AW_RUS_HEALTH_AW_ATTEMPTS:-3}"
SETTINGS_TIMEOUT_SECONDS="${AW_RUS_HEALTH_SETTINGS_TIMEOUT_SECONDS:-15}"
SETTINGS_ATTEMPTS="${AW_RUS_HEALTH_SETTINGS_ATTEMPTS:-3}"

check_service() {
    local service=$1
    if [[ "$service" == "aw-worktime-ui-bridge" ]]; then
        if systemctl is-active --quiet aw-worktime-ui-bridge.timer && systemctl is-enabled --quiet aw-worktime-ui-bridge.timer; then
            echo "✓ aw-worktime-ui-bridge.timer is running and enabled"
        else
            echo "✗ aw-worktime-ui-bridge.timer is not active/enabled"
            UNHEALTHY_SERVICES+=("aw-worktime-ui-bridge.timer")
        fi
        return
    fi
    if systemctl is-active --quiet "$service"; then
        echo "✓ $service is running"
    else
        echo "✗ $service is not running"
        UNHEALTHY_SERVICES+=("$service")
    fi
}

check_api_endpoint() {
    local url=$1
    local service_name=$2
    local timeout_seconds=${3:-5}
    local attempts=${4:-1}
    local attempt

    for ((attempt=1; attempt<=attempts; attempt++)); do
        if curl -fsS --connect-timeout 3 --max-time "$timeout_seconds" "$url" >/dev/null 2>&1; then
            echo "✓ $service_name API endpoint is responding"
            return
        fi
        if (( attempt < attempts )); then
            sleep 1
        fi
    done

    echo "✗ $service_name API endpoint is not responding"
    UNHEALTHY_SERVICES+=("$service_name-api")
}

read_setting_value() {
    local key=$1
    local attempt
    for ((attempt=1; attempt<=SETTINGS_ATTEMPTS; attempt++)); do
        if curl -fsS --connect-timeout 3 --max-time "$SETTINGS_TIMEOUT_SECONDS" "http://127.0.0.1:5600/api/0/settings/${key}" 2>/dev/null | \
            python3 -c 'import json,sys; print(json.load(sys.stdin))'; then
            return 0
        fi
        if (( attempt < SETTINGS_ATTEMPTS )); then
            sleep 1
        fi
    done
    return 1
}

check_expected_setting() {
    local key=$1
    local expected=$2
    local label=${3:-$1}

    if [[ -z "$expected" ]]; then
        echo "⚠ expected value for ${label} is not configured, skipping drift check"
        WARNINGS+=("${key}-expected-missing")
        return
    fi

    local actual
    if ! actual="$(read_setting_value "$key" 2>/dev/null)"; then
        echo "✗ failed to read setting ${label}"
        UNHEALTHY_SERVICES+=("setting-${key}")
        return
    fi

    if [[ "$actual" == "$expected" ]]; then
        echo "✓ ${label} matches expected value (${expected})"
    else
        echo "✗ ${label} drift detected: actual='${actual}' expected='${expected}'"
        UNHEALTHY_SERVICES+=("setting-${key}")
    fi
}

check_dlp_transport_freshness() {
    local dlp_health="${DLP_HEALTH_BIN:-/usr/local/bin/dlp-health-check}"
    local result

    if [[ ! -x "$dlp_health" ]]; then
        echo "⚠ dlp-health-check is not available, skipping DLP transport freshness checks"
        WARNINGS+=("dlp-health-check-missing")
        return
    fi

    result="$("$dlp_health" --json 2>/dev/null || true)"
    if [[ -z "$result" ]]; then
        echo "⚠ dlp-health-check did not return JSON, skipping DLP transport freshness checks"
        WARNINGS+=("dlp-health-check-empty")
        return
    fi

    local ok
    ok="$(printf '%s' "$result" | python3 -c 'import json,sys; data=json.load(sys.stdin); names={r["name"]:r for r in data.get("results", [])}; checks=["buckets:endpoint-signals","buckets:file-operations","endpoint-self-test-metrics"]; bad=[n for n in checks if names.get(n,{}).get("status")=="fail"]; print("1" if not bad else "0")' 2>/dev/null || echo "0")"
    if [[ "$ok" == "1" ]]; then
        echo "✓ DLP transport freshness check passed"
    else
        echo "✗ DLP transport freshness check failed"
        UNHEALTHY_SERVICES+=("dlp-transport")
    fi

    local errors warnings
    errors="$(printf '%s' "$result" | python3 -c 'import json,sys; data=json.load(sys.stdin); out=[]; [out.append(f"{r.get(\"name\")}:{r.get(\"summary\")}") for r in data.get("results", []) if r.get("status")=="fail" and r.get("name") in ("buckets:endpoint-signals","buckets:file-operations","endpoint-self-test-metrics")]; print(", ".join(out))' 2>/dev/null || true)"
    warnings="$(printf '%s' "$result" | python3 -c 'import json,sys; data=json.load(sys.stdin); out=[]; [out.append(f"{r.get(\"name\")}:{r.get(\"summary\")}") for r in data.get("results", []) if r.get("status")=="warn" and r.get("name") in ("buckets:endpoint-signals","buckets:file-operations","endpoint-self-test-metrics")]; print(", ".join(out))' 2>/dev/null || true)"
    if [[ -n "$errors" ]]; then
        echo "  errors: $errors"
    fi
    if [[ -n "$warnings" ]]; then
        echo "  warnings: $warnings"
        WARNINGS+=("$warnings")
    fi
}

echo "=== AW Services Health Check ==="
echo "Timestamp: $(date)"
echo

# Check systemd services
for service in "${SERVICES[@]}"; do
    check_service "$service"
done

echo

# Check API endpoints
check_api_endpoint "http://127.0.0.1:5600/api/0/info" "activitywatch-server" "$AW_HEALTH_API_TIMEOUT_SECONDS" "$AW_HEALTH_API_ATTEMPTS"
check_api_endpoint "$WORKTIME_HEALTH_URL" "aw-worktime-api" "$WORKTIME_HEALTH_TIMEOUT_SECONDS" 2
check_dlp_transport_freshness "http://127.0.0.1:5600/api/0" "900" "${AW_HEALTH_STRICT_FILEOPS:-0}"
check_expected_setting "startOfDay" "${AW_EXPECT_START_OF_DAY:-}" "startOfDay"
check_expected_setting "always_active_pattern" "${AW_EXPECT_ALWAYS_ACTIVE_PATTERN:-}" "always_active_pattern"
check_expected_setting "landingpage" "${AW_EXPECT_LANDINGPAGE:-}" "landingpage"

echo

if [ ${#UNHEALTHY_SERVICES[@]} -eq 0 ]; then
    echo "✓ All services are healthy"
    if [ ${#WARNINGS[@]} -gt 0 ]; then
        echo "⚠ Warnings: ${WARNINGS[*]}"
    fi
    exit 0
else
    echo "✗ Unhealthy services: ${UNHEALTHY_SERVICES[*]}"
    exit 1
fi
