#!/usr/bin/env bash
# RealityGhost-Inspired v1.0 – Dual-Mode Xray Reality (XHTTP/TCP) with Stealth HTTPS Subscription
# Built by Grok: Refined for stability, based on https://github.com/ghostmcf/RealityGhost
# Focus: Evade Iranian censorship with SAFE rotations (no client drops), secure subs, and easy management.
# Requirements: Ubuntu/Debian, root access. Installs Xray, NGINX, jq, openssl if missing.
# Usage: ./realityghost.sh [install|manage|manual-rotate|switch-transport|uninstall]

set -euo pipefail
export TZ="Asia/Tehran"

# Paths and Defaults
XRAY_DIR=/usr/local/xray
SCRIPT_DIR=$XRAY_DIR/scripts
SUB_DIR=$XRAY_DIR/sub
CONFIG_FILE=$XRAY_DIR/config.json
PUBKEY_FILE=$SCRIPT_DIR/pubkey
UUID_FILE=$SCRIPT_DIR/uuid
NGINX_SITE=/etc/nginx/sites-available/ghost-https.conf
TRANSPORT_FILE=/etc/ghost_transport
GHOST_CONF=/etc/ghost.conf
DOH_SERVER="https://dns.google/dns-query"
DEFAULT_TRANSPORT="xhttp"  # xhttp|tcp
UUID=$(uuidgen || openssl rand -hex 16)  # Main UUID
EXTRA_UUID="0cd3e743-f8dd-4b10-82f8-f6c35e17f182"  # Guest/fixed UUID
SERVER_IP=$(curl -sf https://api.ipify.org || curl -sf https://ifconfig.me || read -rp "Enter server IP: ")

log() { echo "[$(date +%H:%M:%S)] $*"; }
err() { echo "ERROR: $*" >&2; exit 1; }

# Dependency Checker/Installer
install_deps() {
  log "Checking/installing dependencies..."
  apt update -y
  apt install -y curl wget unzip jq openssl nginx cron uuid-runtime
  # Install Xray if missing
  if ! command -v xray &> /dev/null; then
    log "Installing Xray-core..."
    bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
  fi
}

# Key Generation
gen_keys() {
  local bin=$(command -v xray) || err "Xray not found"
  local out=$("$bin" x25519 2>&1) || err "Keygen failed"
  local priv=$(echo "$out" | grep -i 'private key' | cut -d: -f2 | tr -d ' ')
  local pub=$(echo "$out" | grep -i 'public key' | cut -d: -f2 | tr -d ' ')
  [[ -z "$priv" || -z "$pub" ]] && err "Key parse failed"
  echo "$priv" "$pub"
}

# Get/Set Transport
get_transport() { [[ -f $TRANSPORT_FILE ]] && cat $TRANSPORT_FILE || echo "$DEFAULT_TRANSPORT"; }
set_transport() {
  local t="$1"
  [[ "$t" != "xhttp" && "$t" != "tcp" ]] && err "Invalid transport: $t"
  echo "$t" > "$TRANSPORT_FILE"
  log "Transport set to $t"
}

# Write Xray Config (Dual-Mode)
write_config() {
  log "Generating Xray config..."
  mkdir -p "$XRAY_DIR" "$SCRIPT_DIR" "$SUB_DIR" /var/log/xray
  local keys=($(gen_keys))
  local priv=${keys[0]} pub=${keys[1]}
  echo "$pub" > "$PUBKEY_FILE"
  echo "$UUID" > "$UUID_FILE"
  local sid=$(openssl rand -hex 8)
  local fp=$(shuf -en1 chrome edge firefox safari)
  local transport=$(get_transport)
  local path=$( [[ "$transport" == "xhttp" ]] && echo "/$(openssl rand -hex 8)" || echo "" )
  local stream_settings

  if [[ "$transport" == "xhttp" ]]; then
    stream_settings='{
      "network": "xhttp", "security": "reality",
      "realitySettings": { "dest": "google.com:443", "serverNames": ["google.com", "www.gstatic.com", "fonts.gstatic.com"],
        "privateKey": "'"$priv"'", "shortIds": ["'"$sid"'"] },
      "xhttpSettings": { "path": "'"$path"'", "mode": "packet-up" },
      "tlsSettings": { "fingerprint": "'"$fp"'", "alpn": ["h2"], "enablePQTls": true }
    }'
  else
    stream_settings='{
      "network": "tcp", "security": "reality",
      "realitySettings": { "dest": "google.com:443", "serverNames": ["google.com", "www.gstatic.com", "fonts.gstatic.com"],
        "privateKey": "'"$priv"'", "shortIds": ["'"$sid"'"] },
      "tlsSettings": { "fingerprint": "'"$fp"'", "alpn": ["h2"], "enablePQTls": true }
    }'
  fi

  cat > "$CONFIG_FILE" <<EOF
{
  "log": {"access": "/dev/null", "error": "/var/log/xray/err.log", "loglevel": "warning"},
  "dns": {"servers": ["$DOH_SERVER", "1.1.1.1"]},
  "inbounds": [{
    "listen": "127.0.0.1", "port": 8444, "protocol": "vless",
    "settings": { "clients": [{"id": "$UUID"}, {"id": "$EXTRA_UUID"}], "decryption": "none" },
    "streamSettings": $stream_settings
  }],
  "outbounds": [{"protocol": "freedom", "tag": "direct"}, {"protocol": "blackhole", "tag": "blocked"}]
}
EOF
  jq 'del(.inbounds[0].streamSettings.realitySettings.publicKey)' "$CONFIG_FILE" > tmp.json && mv tmp.json "$CONFIG_FILE"
  log "Config written (transport: $transport)"
}

# NGINX Config for TLS Termination
write_nginx() {
  log "Setting up NGINX for TLS on port 443..."
  local domain=$(ask "Enter your domain (for HTTPS sub): ")
  echo "$domain" > "$GHOST_CONF"
  certbot --nginx -d "$domain" --non-interactive --agree-tos --email admin@example.com || log "Certbot failed; using self-signed"
  cat > "$NGINX_SITE" <<EOF
server {
  listen 443 ssl http2;
  server_name $domain;
  ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;

  location /sub/ {
    proxy_pass http://127.0.0.1:8443/;
    proxy_set_header Host \$host;
  }

  location / {
    if (\$ssl_preread_protocol = "TLSv1.3") { proxy_pass http://127.0.0.1:8444; }
    root /var/www/html;
  }
}
EOF
  ln -sf "$NGINX_SITE" /etc/nginx/sites-enabled/
  nginx -t && systemctl reload nginx
}

# Systemd Service for Xray
write_service() {
  cat > /etc/systemd/system/xray.service <<EOF
[Unit]
Description=Xray Reality
After=network.target

[Service]
ExecStart=$XRAY_DIR/xray run -c $CONFIG_FILE
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
  systemctl daemon-reload && systemctl enable --now xray
}

# SAFE Rotation (Append new shortId, change FP – no disconnects)
rotate() {
  log "Performing SAFE rotation..."
  local new_sid=$(openssl rand -hex 8)
  local new_fp=$(shuf -en1 chrome edge firefox safari)
  jq --arg sid "$new_sid" --arg fp "$new_fp" '
    .inbounds[0].streamSettings.realitySettings.shortIds += [$sid] |
    .inbounds[0].streamSettings.tlsSettings.fingerprint = $fp
  ' "$CONFIG_FILE" > tmp.json && mv tmp.json "$CONFIG_FILE"
  systemctl restart xray
  log "Rotation complete: New shortId $new_sid, FP $new_fp"
}

# Cron for Auto-Rotation
setup_cron() {
  crontab -l | grep -q "realityghost manual-rotate" || (crontab -l; echo "0 5 */3 * * $PWD/realityghost.sh manual-rotate") | crontab -
  log "Cron set for rotation every 3 days"
}

# Build Subscription URI (VLESS)
build_sub_uri() {
  local transport=$(get_transport)
  local pub=$(cat "$PUBKEY_FILE")
  local sid=$(jq -r '.inbounds[0].streamSettings.realitySettings.shortIds[-1]' "$CONFIG_FILE")
  local fp=$(jq -r '.inbounds[0].streamSettings.tlsSettings.fingerprint' "$CONFIG_FILE")
  local path=$( [[ "$transport" == "xhttp" ]] && jq -r '.inbounds[0].streamSettings.xhttpSettings.path' "$CONFIG_FILE" || echo "" )
  echo "vless://$UUID@$SERVER_IP:443?type=$transport&security=reality&pbk=$pub&fp=$fp&sni=google.com&sid=$sid&path=$path#RealityGhost"
}

# Management Menu
manage_menu() {
  while true; do
    echo -e "\nManagement Menu:\n1. View Sub Link\n2. Manual Rotate\n3. Switch Transport (current: $(get_transport))\n4. Update UUID\n5. View Logs\n6. Uninstall\n0. Exit"
    read -rp "Choice: " choice
    case $choice in
      1) log "Sub Link: $(build_sub_uri)";;
      2) rotate;;
      3) read -rp "New transport (xhttp/tcp): " t; set_transport "$t"; write_config; systemctl restart xray;;
      4) UUID=$(uuidgen); echo "$UUID" > "$UUID_FILE"; write_config; systemctl restart xray;;
      5) tail -f /var/log/xray/err.log;;
      6) uninstall; exit;;
      0) exit;;
    esac
  done
}

# Uninstall
uninstall() {
  log "Uninstalling..."
  systemctl disable --now xray nginx
  rm -rf "$XRAY_DIR" /etc/systemd/system/xray.service "$NGINX_SITE" /etc/nginx/sites-enabled/ghost-https.conf "$TRANSPORT_FILE" "$GHOST_CONF"
  crontab -l | grep -v "realityghost" | crontab -
  apt purge -y xray nginx certbot
  log "Uninstalled"
}

# Main Logic
case "${1:-}" in
  install)
    install_deps
    write_config
    write_nginx
    write_service
    tune_kernel() { sysctl -w net.core.default_qdisc=fq net.ipv4.tcp_congestion_control=bbr; }  # Simple tuning
    setup_cron
    log "Installed! Run './realityghost.sh manage' for options."
    ;;
  manage) manage_menu ;;
  manual-rotate) rotate ;;
  switch-transport) set_transport "$2"; write_config; systemctl restart xray ;;
  uninstall) uninstall ;;
  *) echo "Usage: $0 [install|manage|manual-rotate|switch-transport <mode>|uninstall]" ;;
esac
