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

PHASE="$1"
HOSTNAME="$2"
EMAIL="$3"
ROOT_PASSWORD="${4:-}"

# Validate inputs
if ! [[ "$HOSTNAME" =~ ^[a-zA-Z0-9._-]+$ ]]; then
    echo "ERROR: invalid hostname" >&2; exit 1
fi
if ! [[ "$EMAIL" =~ ^[^@]+@[^@]+$ ]]; then
    echo "ERROR: invalid email" >&2; exit 1
fi

CERT_DIR="/etc/letsencrypt/live/${HOSTNAME}"
CERT_PATH="${CERT_DIR}/fullchain.pem"
KEY_PATH="${CERT_DIR}/privkey.pem"

if [ "$PHASE" = "install" ]; then
    echo "=== Phase 1: Install binary and dependencies ==="

    # Install the layover binary
    install -m 755 /tmp/layover /usr/local/bin/layover

    # Create dedicated service user (no home, no login)
    useradd --system --no-create-home --shell /usr/sbin/nologin layover 2>/dev/null || true

    # Install certbot via snap
    snap install --classic certbot 2>/dev/null || true
    ln -sf /snap/bin/certbot /usr/bin/certbot

    # Set random root password (unguessable, stored in terraform state)
    if [ -n "$ROOT_PASSWORD" ]; then
        echo "root:${ROOT_PASSWORD}" | chpasswd
    fi

    # Install and configure fail2ban
    apt-get update -qq
    apt-get install -y -qq fail2ban > /dev/null
    cat > /etc/fail2ban/jail.local <<'F2B'
[sshd]
enabled = true
mode = aggressive
maxretry = 5
findtime = 600
bantime = 3600
F2B
    systemctl enable fail2ban
    systemctl restart fail2ban

    # Harden SSH
    sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
    sed -i 's/^#\?X11Forwarding.*/X11Forwarding no/' /etc/ssh/sshd_config
    sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
    sed -i 's/^#\?MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config
    systemctl reload ssh 2>/dev/null || true

    # Create systemd service — hardened
    cat > /etc/systemd/system/layover.service <<UNIT
[Unit]
Description=Layover TCP relay server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=layover
Group=layover
ExecStart=/usr/local/bin/layover serve --cert ${CERT_PATH} --key ${KEY_PATH}
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

# Capabilities
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

# Filesystem
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadOnlyPaths=/etc/letsencrypt

# Kernel
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true

# Other
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictRealtime=true
RestrictSUIDSGID=true
RestrictAddressFamilies=AF_INET AF_INET6
RestrictNamespaces=true
SystemCallArchitectures=native
UMask=0077

[Install]
WantedBy=multi-user.target
UNIT

    # Certbot renewal hook — restart layover to pick up new certs
    mkdir -p /etc/letsencrypt/renewal-hooks/post
    cat > /etc/letsencrypt/renewal-hooks/post/layover-restart.sh <<'HOOK'
#!/bin/bash
systemctl restart layover
HOOK
    chmod +x /etc/letsencrypt/renewal-hooks/post/layover-restart.sh

    systemctl daemon-reload
    echo "=== Phase 1 complete ==="

elif [ "$PHASE" = "certbot" ]; then
    echo "=== Phase 2: Obtain TLS certificate and start service ==="

    # Wait for DNS propagation
    echo "Waiting for DNS to resolve ${HOSTNAME}..."
    for i in $(seq 1 30); do
        if host "$HOSTNAME" >/dev/null 2>&1; then
            echo "DNS resolved."
            break
        fi
        echo "  Attempt $i/30..."
        sleep 10
    done

    # Get TLS certificate (standalone mode uses port 80 for ACME challenge)
    certbot certonly \
        --standalone \
        --non-interactive \
        --agree-tos \
        --email "$EMAIL" \
        --domain "$HOSTNAME" \
        --preferred-challenges http

    # Fix cert permissions so layover user can read them
    chmod 0755 /etc/letsencrypt/live
    chmod 0755 /etc/letsencrypt/archive
    chmod 0644 /etc/letsencrypt/archive/*/fullchain*.pem
    chmod 0644 /etc/letsencrypt/archive/*/cert*.pem
    chmod 0640 /etc/letsencrypt/archive/*/privkey*.pem
    chgrp layover /etc/letsencrypt/archive/*/privkey*.pem

    # Start the relay
    systemctl enable layover
    systemctl start layover

    echo "=== Phase 2 complete: Layover is running ==="
fi
