#!/usr/bin/env bash
# Run deterministic media/device contracts and emit Atlas quality metrics.
set -euo pipefail

ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
REPORT_DIR="${ROOT_DIR}/target/media-reliability-gate"
TEST_LOG="${REPORT_DIR}/cargo-test.log"
SUMMARY_JSON="${REPORT_DIR}/summary.json"
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
METRICS_FILE="${REPORT_DIR}/metrics.prom"
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
PUSHGATEWAY_JOB=${LESAVKA_MEDIA_GATE_PUSHGATEWAY_JOB:-lesavka-media-reliability-gate}

mkdir -p "${REPORT_DIR}"
cd "${ROOT_DIR}"

branch=${BRANCH_NAME:-${GIT_BRANCH:-}}
if [[ -z "${branch}" ]]; then
  branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
fi
commit=${GIT_COMMIT:-}
if [[ -z "${commit}" ]]; then
  commit=$(git rev-parse --short HEAD 2>/dev/null || echo unknown)
fi
build_url=${BUILD_URL:-}

MEDIA_TESTS=(
  --test client_camera_include_contract
  --test client_launcher_runtime_contract
  --test client_microphone_include_contract
  --test client_microphone_source_contract
  --test client_output_video_include_contract
  --test handshake_camera_contract
  --test server_camera_contract
  --test server_camera_runtime_contract
  --test server_upstream_media_contract
  --test server_uvc_runtime_contract
  --test server_video_include_contract
  --test server_video_sink_smoke_contract
  --test server_video_sinks_include_contract
  --test video_downstream_feed_contract
  --test video_support_contract
)

start_seconds=$(date +%s)
status=0
set +e
cargo test -p lesavka_testing "${MEDIA_TESTS[@]}" --color never 2>&1 | tee "${TEST_LOG}"
status=${PIPESTATUS[0]}
set -e
end_seconds=$(date +%s)
duration_seconds=$((end_seconds - start_seconds))

python3 - "${SUMMARY_JSON}" "${SUMMARY_TXT}" "${METRICS_FILE}" "${status}" "${duration_seconds}" "${branch}" "${commit}" "${build_url}" "${REPORT_DIR}" <<'PY'
import json
import pathlib
import sys
from datetime import datetime, timezone

summary_path = pathlib.Path(sys.argv[1])
text_path = pathlib.Path(sys.argv[2])
metrics_path = pathlib.Path(sys.argv[3])
status = int(sys.argv[4])
duration_seconds = int(sys.argv[5])
branch = sys.argv[6]
commit = sys.argv[7]
build_url = sys.argv[8]
report_dir = pathlib.Path(sys.argv[9])
manual_report = report_dir / 'manual-soak.json'

def esc(value: str) -> str:
    return value.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"')

manual_checks = [
    {
        'name': 'zoom_equivalent_webcam_consumer',
        'status': 'not_applicable' if not manual_report.exists() else 'reported',
        'why': 'requires a real UVC/HDMI consumer such as Zoom, Teams, Slack, or capture software',
    },
    {
        'name': 'ten_minute_soak',
        'status': 'not_applicable' if not manual_report.exists() else 'reported',
        'why': 'requires sustained live hardware output and should be attached as manual-soak.json',
    },
    {
        'name': 'hdmi_capture_adapter_path',
        'status': 'not_applicable' if not manual_report.exists() else 'reported',
        'why': 'requires the Theia HDMI -> UGREEN -> Tethys USB path',
    },
]

tracked_signals = [
    'frame_count',
    'effective_fps',
    'dropped_frames',
    'queue_depth',
    'max_inter_frame_gap_ms',
    'decode_errors',
    'appsrc_push_failures',
    'artifact_score',
    'latency_estimate_ms',
    'idr_recovery_after_drop',
    'synthetic_moving_pattern_distortion',
]

summary = {
    'suite': 'lesavka',
    'branch': branch,
    'commit': commit,
    'build_url': build_url,
    'generated_at': datetime.now(timezone.utc).isoformat(),
    'status': 'ok' if status == 0 else 'failed',
    'duration_seconds': duration_seconds,
    'deterministic_tests': 'cargo test -p lesavka_testing media reliability contract subset',
    'tracked_media_signals': tracked_signals,
    'manual_checks': manual_checks,
}
summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + '\n', encoding='utf-8')

lines = [
    'media reliability gate report',
    f'status: {summary["status"]}',
    f'branch: {branch}',
    f'commit: {commit}',
    f'duration_seconds: {duration_seconds}',
    '',
    'deterministic coverage',
    '- bounded appsrc/appsink queue contracts',
    '- stale-frame/drop-over-latency contracts',
    '- local monotonic timestamp contracts',
    '- IDR/keyframe recovery contracts',
    '- HDMI/UVC sink construction contracts',
    '- preview telemetry and freeze-signal contracts',
    '',
    'manual hardware evidence slots',
]
for check in manual_checks:
    lines.append(f'- {check["name"]}: {check["status"]} ({check["why"]})')
text_path.write_text('\n'.join(lines) + '\n', encoding='utf-8')

labels = f'suite="lesavka",branch="{esc(branch)}",commit="{esc(commit)}"'
ok = 1 if status == 0 else 0
failed = 0 if status == 0 else 1
metrics = [
    '# HELP platform_quality_gate_checks_total Check outcomes from the latest lesavka gate run.',
    '# TYPE platform_quality_gate_checks_total gauge',
    f'platform_quality_gate_checks_total{{{labels},check="media_reliability",status="ok"}} {ok}',
    f'platform_quality_gate_checks_total{{{labels},check="media_reliability",status="failed"}} {failed}',
    '# HELP lesavka_media_reliability_manual_check_info Manual media reliability evidence slots.',
    '# TYPE lesavka_media_reliability_manual_check_info gauge',
]
for check in manual_checks:
    metrics.append(
        f'lesavka_media_reliability_manual_check_info{{{labels},check="{esc(check["name"])}",status="{esc(check["status"])}"}} 1'
    )
metrics_path.write_text('\n'.join(metrics) + '\n', encoding='utf-8')
print(text_path.read_text(encoding='utf-8'))
PY

if [[ -n "${PUSHGATEWAY_URL}" ]]; then
  curl --fail --silent --show-error \
    --data-binary @"${METRICS_FILE}" \
    "${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka" || status=$?
fi

exit "${status}"
