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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

ARTIFACTS_DIR="${ARTIFACTS_DIR:-$ROOT_DIR/artifacts}"
OUT_JSON="${OUT_JSON:-$ARTIFACTS_DIR/release_gate_report.json}"
OUT_MD="${OUT_MD:-$ARTIFACTS_DIR/release_gate_report.md}"

MIXED_REPORT="${MIXED_REPORT:-$ARTIFACTS_DIR/mixed_workload_report.json}"
SOAK_REPORT="${SOAK_REPORT:-$ARTIFACTS_DIR/soak_failure_report.json}"
CONCURRENT_REPORT="${CONCURRENT_REPORT:-$ARTIFACTS_DIR/concurrent_stress_report.json}"
TUNING_REPORT="${TUNING_REPORT:-$ARTIFACTS_DIR/tuning_sweep_report.json}"

ALPHA_MAX_ERROR_RATE="${ALPHA_MAX_ERROR_RATE:-0.01}"
ALPHA_MAX_P95_MICROS="${ALPHA_MAX_P95_MICROS:-10000}"
ALPHA_MAX_P99_MICROS="${ALPHA_MAX_P99_MICROS:-15000}"
ALPHA_MIN_CONCURRENT_INGEST_P50_EPS="${ALPHA_MIN_CONCURRENT_INGEST_P50_EPS:-50000}"
ALPHA_MIN_BURST_INGEST_EPS="${ALPHA_MIN_BURST_INGEST_EPS:-200000}"

BETA_MAX_ERROR_RATE="${BETA_MAX_ERROR_RATE:-0.005}"
BETA_MAX_P95_MICROS="${BETA_MAX_P95_MICROS:-5000}"
BETA_MAX_P99_MICROS="${BETA_MAX_P99_MICROS:-8000}"
BETA_MIN_CONCURRENT_INGEST_P50_EPS="${BETA_MIN_CONCURRENT_INGEST_P50_EPS:-70000}"
BETA_MIN_BURST_INGEST_EPS="${BETA_MIN_BURST_INGEST_EPS:-250000}"

require_file() {
  local path="$1"
  if [[ ! -f "$path" ]]; then
    echo "missing required report: $path" >&2
    exit 2
  fi
}

bool_from_json() {
  local key="$1"
  local file="$2"
  grep -E "\"$key\"[[:space:]]*:" "$file" | tail -n1 | sed -nE 's/.*: (true|false).*/\1/p'
}

num_from_json() {
  local key="$1"
  local file="$2"
  grep -E "\"$key\"[[:space:]]*:" "$file" | tail -n1 | sed -nE 's/.*: ([^,}]+).*/\1/p'
}

require_file "$MIXED_REPORT"
require_file "$SOAK_REPORT"
require_file "$CONCURRENT_REPORT"
require_file "$TUNING_REPORT"

mixed_pass="$(bool_from_json "overall_pass" "$MIXED_REPORT")"
soak_pass="$(bool_from_json "overall_pass" "$SOAK_REPORT")"
concurrent_pass="$(bool_from_json "overall_pass" "$CONCURRENT_REPORT")"

soak_error_rate="$(num_from_json "error_rate" "$SOAK_REPORT")"
concurrent_error_rate="$(num_from_json "error_rate" "$CONCURRENT_REPORT")"
soak_p95="$(grep -E "\"p95_micros\"[[:space:]]*:" "$SOAK_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
soak_p99="$(grep -E "\"p99_micros\"[[:space:]]*:" "$SOAK_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
concurrent_p95="$(grep -E "\"p95_micros\"[[:space:]]*:" "$CONCURRENT_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
concurrent_p99="$(grep -E "\"p99_micros\"[[:space:]]*:" "$CONCURRENT_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
concurrent_ingest_p50="$(grep -E "\"p50\"[[:space:]]*:" "$CONCURRENT_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
mixed_burst_ingest_eps="$(grep -E "\"burst\"[[:space:]]*:" "$MIXED_REPORT" | sed -nE 's/.*"ingest_events_per_sec": ([^,}]+).*/\1/p' | tail -n1)"
soak_recover_failures="$(grep -E "\"recover_failures\"[[:space:]]*:" "$SOAK_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"
best_config="$(grep -E "\"best_config\"[[:space:]]*:" "$TUNING_REPORT" | sed -nE 's/.*: "([^"]+)".*/\1/p' | tail -n1)"
best_burst_p99="$(grep -E "\"best_burst_query_p99\"[[:space:]]*:" "$TUNING_REPORT" | sed -nE 's/.*: ([^,}]+).*/\1/p' | tail -n1)"

check_le() {
  awk -v v="$1" -v max="$2" 'BEGIN { exit !(v <= max) }'
}
check_ge() {
  awk -v v="$1" -v min="$2" 'BEGIN { exit !(v >= min) }'
}

alpha_pass=true
beta_pass=true

if [[ "$mixed_pass" != "true" || "$soak_pass" != "true" || "$concurrent_pass" != "true" ]]; then
  alpha_pass=false
  beta_pass=false
fi

check_le "$soak_error_rate" "$ALPHA_MAX_ERROR_RATE" || alpha_pass=false
check_le "$concurrent_error_rate" "$ALPHA_MAX_ERROR_RATE" || alpha_pass=false
check_le "$soak_p95" "$ALPHA_MAX_P95_MICROS" || alpha_pass=false
check_le "$soak_p99" "$ALPHA_MAX_P99_MICROS" || alpha_pass=false
check_le "$concurrent_p95" "$ALPHA_MAX_P95_MICROS" || alpha_pass=false
check_le "$concurrent_p99" "$ALPHA_MAX_P99_MICROS" || alpha_pass=false
check_ge "$concurrent_ingest_p50" "$ALPHA_MIN_CONCURRENT_INGEST_P50_EPS" || alpha_pass=false
check_ge "$mixed_burst_ingest_eps" "$ALPHA_MIN_BURST_INGEST_EPS" || alpha_pass=false
check_le "$soak_recover_failures" 0 || alpha_pass=false

check_le "$soak_error_rate" "$BETA_MAX_ERROR_RATE" || beta_pass=false
check_le "$concurrent_error_rate" "$BETA_MAX_ERROR_RATE" || beta_pass=false
check_le "$soak_p95" "$BETA_MAX_P95_MICROS" || beta_pass=false
check_le "$soak_p99" "$BETA_MAX_P99_MICROS" || beta_pass=false
check_le "$concurrent_p95" "$BETA_MAX_P95_MICROS" || beta_pass=false
check_le "$concurrent_p99" "$BETA_MAX_P99_MICROS" || beta_pass=false
check_ge "$concurrent_ingest_p50" "$BETA_MIN_CONCURRENT_INGEST_P50_EPS" || beta_pass=false
check_ge "$mixed_burst_ingest_eps" "$BETA_MIN_BURST_INGEST_EPS" || beta_pass=false
check_le "$soak_recover_failures" 0 || beta_pass=false

overall_pass=false
if [[ "$alpha_pass" == "true" ]]; then
  overall_pass=true
fi

TIMESTAMP_UTC="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
COMMIT_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")"

mkdir -p "$ARTIFACTS_DIR"

cat >"$OUT_JSON" <<EOF
{
  "timestamp_utc": "$TIMESTAMP_UTC",
  "commit_sha": "$COMMIT_SHA",
  "inputs": {
    "mixed_report": "$(basename "$MIXED_REPORT")",
    "soak_report": "$(basename "$SOAK_REPORT")",
    "concurrent_report": "$(basename "$CONCURRENT_REPORT")",
    "tuning_report": "$(basename "$TUNING_REPORT")"
  },
  "observed": {
    "mixed_pass": $mixed_pass,
    "soak_pass": $soak_pass,
    "concurrent_pass": $concurrent_pass,
    "soak_error_rate": $soak_error_rate,
    "concurrent_error_rate": $concurrent_error_rate,
    "soak_p95_micros": $soak_p95,
    "soak_p99_micros": $soak_p99,
    "concurrent_p95_micros": $concurrent_p95,
    "concurrent_p99_micros": $concurrent_p99,
    "concurrent_ingest_p50_eps": $concurrent_ingest_p50,
    "mixed_burst_ingest_eps": $mixed_burst_ingest_eps,
    "soak_recover_failures": $soak_recover_failures,
    "tuning_best_config": "$best_config",
    "tuning_best_burst_query_p99": $best_burst_p99
  },
  "thresholds": {
    "alpha": {
      "max_error_rate": $ALPHA_MAX_ERROR_RATE,
      "max_p95_micros": $ALPHA_MAX_P95_MICROS,
      "max_p99_micros": $ALPHA_MAX_P99_MICROS,
      "min_concurrent_ingest_p50_eps": $ALPHA_MIN_CONCURRENT_INGEST_P50_EPS,
      "min_mixed_burst_ingest_eps": $ALPHA_MIN_BURST_INGEST_EPS
    },
    "beta": {
      "max_error_rate": $BETA_MAX_ERROR_RATE,
      "max_p95_micros": $BETA_MAX_P95_MICROS,
      "max_p99_micros": $BETA_MAX_P99_MICROS,
      "min_concurrent_ingest_p50_eps": $BETA_MIN_CONCURRENT_INGEST_P50_EPS,
      "min_mixed_burst_ingest_eps": $BETA_MIN_BURST_INGEST_EPS
    }
  },
  "decisions": {
    "alpha_ready": $alpha_pass,
    "beta_ready": $beta_pass,
    "overall_pass": $overall_pass
  }
}
EOF

cat >"$OUT_MD" <<EOF
# Release Gate Report

- Timestamp (UTC): $TIMESTAMP_UTC
- Commit: $COMMIT_SHA

## Inputs
- mixed: $(basename "$MIXED_REPORT")
- soak: $(basename "$SOAK_REPORT")
- concurrent: $(basename "$CONCURRENT_REPORT")
- tuning: $(basename "$TUNING_REPORT")

## Observed
- mixed_pass: $mixed_pass
- soak_pass: $soak_pass
- concurrent_pass: $concurrent_pass
- soak_error_rate: $soak_error_rate
- concurrent_error_rate: $concurrent_error_rate
- soak_p95_micros: $soak_p95
- soak_p99_micros: $soak_p99
- concurrent_p95_micros: $concurrent_p95
- concurrent_p99_micros: $concurrent_p99
- concurrent_ingest_p50_eps: $concurrent_ingest_p50
- mixed_burst_ingest_eps: $mixed_burst_ingest_eps
- soak_recover_failures: $soak_recover_failures
- tuning_best_config: $best_config
- tuning_best_burst_query_p99: $best_burst_p99

## Decisions
- alpha_ready: $alpha_pass
- beta_ready: $beta_pass
- overall_pass: $overall_pass
EOF

echo "Wrote:"
echo "  $OUT_JSON"
echo "  $OUT_MD"

if [[ "$overall_pass" != "true" ]]; then
  echo "release gate failed" >&2
  exit 1
fi
