#!/bin/sh
set -e

# Pilot Protocol installer
# Usage:
#   Install:    curl -fsSL https://pilotprotocol.network/install.sh | sh
#   RC build:   PILOT_RC=1 curl -fsSL https://pilotprotocol.network/install.sh | sh
#   Uninstall:  curl -fsSL https://pilotprotocol.network/install.sh | sh -s uninstall

REPO="TeoSlayer/pilotprotocol"
REGISTRY="34.71.57.205:9000"
BEACON="34.71.57.205:9001"
PILOT_DIR="$HOME/.pilot"
BIN_DIR="$PILOT_DIR/bin"

# --- Uninstall ---

if [ "${1}" = "uninstall" ]; then
    echo ""
    echo "  Uninstalling Pilot Protocol..."
    echo ""

    OS=$(uname -s | tr '[:upper:]' '[:lower:]')

    # Stop daemon
    if [ -x "$BIN_DIR/pilotctl" ]; then
        "$BIN_DIR/pilotctl" daemon stop 2>/dev/null || true
        "$BIN_DIR/pilotctl" gateway stop 2>/dev/null || true
    elif command -v pilotctl >/dev/null 2>&1; then
        pilotctl daemon stop 2>/dev/null || true
        pilotctl gateway stop 2>/dev/null || true
    fi

    # Remove system services (daemon + updater)
    if [ "$OS" = "linux" ]; then
        if [ "$(id -u)" = "0" ] || sudo -n true 2>/dev/null; then
            for svc in pilot-daemon pilot-updater; do
                if [ -f "/etc/systemd/system/${svc}.service" ]; then
                    sudo systemctl stop "$svc" 2>/dev/null || true
                    sudo systemctl disable "$svc" 2>/dev/null || true
                    sudo rm -f "/etc/systemd/system/${svc}.service"
                fi
            done
            sudo systemctl daemon-reload
            echo "  Removed systemd services"
        else
            echo "  Skipped systemd removal (run with sudo to remove)"
        fi
    fi
    if [ "$OS" = "darwin" ]; then
        for label in com.vulturelabs.pilot-daemon com.vulturelabs.pilot-updater; do
            PLIST="$HOME/Library/LaunchAgents/${label}.plist"
            if [ -f "$PLIST" ]; then
                launchctl unload "$PLIST" 2>/dev/null || true
                rm -f "$PLIST"
            fi
        done
        echo "  Removed LaunchAgents"
    fi

    # Remove pilot directory (binaries, config, identity, received files)
    if [ -d "$PILOT_DIR" ]; then
        rm -rf "$PILOT_DIR"
        echo "  Removed $PILOT_DIR"
    fi

    # Remove socket
    rm -f /tmp/pilot.sock

    echo ""
    echo "  Pilot Protocol uninstalled."
    echo ""
    exit 0
fi

# Detect platform
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$ARCH" in
    x86_64)  ARCH="amd64" ;;
    aarch64) ARCH="arm64" ;;
    arm64)   ARCH="arm64" ;;
    *)       echo "Error: unsupported architecture: $ARCH"; exit 1 ;;
esac

case "$OS" in
    linux|darwin) ;;
    *) echo "Error: unsupported OS: $OS"; exit 1 ;;
esac

echo ""
echo "  Pilot Protocol"
echo "  The network stack for AI agents."
echo ""
echo "  Platform:   ${OS}/${ARCH}"
echo "  Registry:   ${REGISTRY}"
echo "  Beacon:     ${BEACON}"
echo ""

# --- Resolve email ---

EMAIL="${PILOT_EMAIL:-}"

# On fresh install, email is required (like certbot)
if [ -z "$EMAIL" ] && [ ! -x "$BIN_DIR/pilotctl" ]; then
    # Check if account.json already has an email
    if [ -f "$PILOT_DIR/account.json" ]; then
        EMAIL=$(grep '"email"' "$PILOT_DIR/account.json" 2>/dev/null | head -1 | cut -d'"' -f4 || true)
    fi
    if [ -z "$EMAIL" ]; then
        printf "  Email (for account recovery): "
        read EMAIL < /dev/tty
        if [ -z "$EMAIL" ]; then
            echo "  Error: email is required. Set PILOT_EMAIL or enter when prompted."
            exit 1
        fi
    fi
fi

# --- Detect existing installation ---

UPDATING=false
if [ -x "$BIN_DIR/pilotctl" ]; then
    UPDATING=true
    CURRENT=$("$BIN_DIR/pilotctl" version 2>/dev/null || echo "unknown")
    echo "  Existing install detected (${CURRENT})"
    echo "  Updating binaries..."
    echo ""
fi

# --- Download or build ---

TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

# Try downloading a release first
# PILOT_RC=1 opts into release candidates (pre-releases)
if [ "${PILOT_RC:-}" = "1" ]; then
    TAG=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases" 2>/dev/null | grep '"tag_name"' | head -1 | cut -d'"' -f4 || true)
else
    TAG=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" 2>/dev/null | grep '"tag_name"' | head -1 | cut -d'"' -f4 || true)
fi

if [ -n "$TAG" ]; then
    ARCHIVE="pilot-${OS}-${ARCH}.tar.gz"
    URL="https://github.com/${REPO}/releases/download/${TAG}/${ARCHIVE}"
    echo "Downloading ${TAG}..."
    if curl -fsSL "$URL" -o "$TMPDIR/$ARCHIVE" 2>/dev/null; then
        tar -xzf "$TMPDIR/$ARCHIVE" -C "$TMPDIR"
    else
        TAG=""
    fi
fi

if [ -z "$TAG" ]; then
    echo "No release available. Building from source..."
    if ! command -v go >/dev/null 2>&1; then
        echo "Error: Go is required to build from source."
        echo "Install Go: https://go.dev/dl/"
        exit 1
    fi
    if ! command -v git >/dev/null 2>&1; then
        echo "Error: git is required to build from source."
        exit 1
    fi
    echo "Cloning..."
    git clone --depth 1 "https://github.com/${REPO}.git" "$TMPDIR/src" >/dev/null 2>&1
    echo "Building daemon..."
    CGO_ENABLED=0 go build -o "$TMPDIR/pilot-daemon" "$TMPDIR/src/cmd/daemon"
    echo "Building pilotctl..."
    CGO_ENABLED=0 go build -o "$TMPDIR/pilotctl" "$TMPDIR/src/cmd/pilotctl"
    echo "Building gateway..."
    CGO_ENABLED=0 go build -o "$TMPDIR/pilot-gateway" "$TMPDIR/src/cmd/gateway"
    echo "Building updater..."
    CGO_ENABLED=0 go build -o "$TMPDIR/pilot-updater" "$TMPDIR/src/cmd/updater"
fi

# --- Install binaries to ~/.pilot/bin ---

echo "Installing binaries..."
mkdir -p "$BIN_DIR"

# Handle both naming conventions (release: daemon/gateway, source: pilot-daemon/pilot-gateway)
if [ -f "$TMPDIR/daemon" ]; then
    cp "$TMPDIR/daemon" "$BIN_DIR/pilot-daemon"
else
    cp "$TMPDIR/pilot-daemon" "$BIN_DIR/pilot-daemon"
fi
cp "$TMPDIR/pilotctl" "$BIN_DIR/pilotctl"
if [ -f "$TMPDIR/gateway" ]; then
    cp "$TMPDIR/gateway" "$BIN_DIR/pilot-gateway"
else
    cp "$TMPDIR/pilot-gateway" "$BIN_DIR/pilot-gateway"
fi
if [ -f "$TMPDIR/updater" ]; then
    cp "$TMPDIR/updater" "$BIN_DIR/pilot-updater"
elif [ -f "$TMPDIR/pilot-updater" ]; then
    cp "$TMPDIR/pilot-updater" "$BIN_DIR/pilot-updater"
fi
chmod 755 "$BIN_DIR/pilot-daemon" "$BIN_DIR/pilotctl" "$BIN_DIR/pilot-gateway"
[ -f "$BIN_DIR/pilot-updater" ] && chmod 755 "$BIN_DIR/pilot-updater"

# --- Symlink to /usr/local/bin if writable, otherwise skip ---

LINK_DIR="/usr/local/bin"
if [ -d "$LINK_DIR" ] && [ -w "$LINK_DIR" ]; then
    ln -sf "$BIN_DIR/pilot-daemon" "$LINK_DIR/pilot-daemon"
    ln -sf "$BIN_DIR/pilotctl" "$LINK_DIR/pilotctl"
    ln -sf "$BIN_DIR/pilot-gateway" "$LINK_DIR/pilot-gateway"
    [ -f "$BIN_DIR/pilot-updater" ] && ln -sf "$BIN_DIR/pilot-updater" "$LINK_DIR/pilot-updater"
    echo "  Symlinked to ${LINK_DIR}"
fi

# --- Update: stop here, skip config/service/PATH setup ---

if [ "$UPDATING" = true ]; then
    # Write version file for the auto-updater
    [ -n "$TAG" ] && echo "$TAG" > "$BIN_DIR/.pilot-version"
    echo ""
    echo "Updated to ${TAG:-source}:"
    echo "  pilot-daemon    ${BIN_DIR}/pilot-daemon"
    echo "  pilotctl         ${BIN_DIR}/pilotctl"
    echo "  pilot-gateway    ${BIN_DIR}/pilot-gateway"
    echo "  pilot-updater    ${BIN_DIR}/pilot-updater"
    echo ""
    echo "Restart the daemon to use the new version:"
    echo "  pilotctl daemon stop && pilotctl daemon start"
    echo ""
    exit 0
fi

# --- Fresh install: write config ---

cat > "$PILOT_DIR/config.json" <<CONF
{
  "registry": "${REGISTRY}",
  "beacon": "${BEACON}",
  "socket": "/tmp/pilot.sock",
  "encrypt": true,
  "identity": "${PILOT_DIR}/identity.json",
  "email": "${EMAIL}"
}
CONF

echo "Config written to ${PILOT_DIR}/config.json"

# --- Set up system service ---

if [ "$OS" = "linux" ] && command -v systemctl >/dev/null 2>&1; then
    CAN_SUDO=false
    if [ "$(id -u)" = "0" ] || sudo -n true 2>/dev/null; then
        CAN_SUDO=true
    fi
    if [ "$CAN_SUDO" = true ]; then
    echo "Setting up systemd service..."
    HOSTNAME_FLAG=""
    if [ -n "$PILOT_HOSTNAME" ]; then
        HOSTNAME_FLAG="-hostname $PILOT_HOSTNAME"
    fi
    PUBLIC_FLAG=""
    if [ -n "$PILOT_PUBLIC" ]; then
        PUBLIC_FLAG="-public"
    fi
    sudo tee /etc/systemd/system/pilot-daemon.service >/dev/null <<SVC
[Unit]
Description=Pilot Protocol Daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=$(whoami)
ExecStart=${BIN_DIR}/pilot-daemon \\
  -registry ${REGISTRY} \\
  -beacon ${BEACON} \\
  -listen :4000 \\
  -socket /tmp/pilot.sock \\
  -identity ${PILOT_DIR}/identity.json \\
  -email ${EMAIL} \\
  -encrypt ${HOSTNAME_FLAG} ${PUBLIC_FLAG}
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
SVC
    # Auto-updater service
    if [ -f "$BIN_DIR/pilot-updater" ]; then
    sudo tee /etc/systemd/system/pilot-updater.service >/dev/null <<USVC
[Unit]
Description=Pilot Protocol Auto-Updater
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=$(whoami)
ExecStart=${BIN_DIR}/pilot-updater \\
  -install-dir ${BIN_DIR}
Restart=always
RestartSec=30

[Install]
WantedBy=multi-user.target
USVC
    fi

    sudo systemctl daemon-reload
    echo "  Service: pilot-daemon.service"
    echo "  Service: pilot-updater.service (auto-updates)"
    echo "  Start:   sudo systemctl start pilot-daemon pilot-updater"
    echo "  Enable:  sudo systemctl enable pilot-daemon pilot-updater"
    else
    echo "  Skipped systemd setup (run as root or with passwordless sudo to enable)"
    fi
fi

if [ "$OS" = "darwin" ]; then
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.vulturelabs.pilot-daemon.plist"
    mkdir -p "$PLIST_DIR"
    EXTRA_ARGS=""
    if [ -n "$PILOT_HOSTNAME" ]; then
        EXTRA_ARGS="${EXTRA_ARGS}        <string>-hostname</string>
        <string>${PILOT_HOSTNAME}</string>
"
    fi
    if [ -n "$PILOT_PUBLIC" ]; then
        EXTRA_ARGS="${EXTRA_ARGS}        <string>-public</string>
"
    fi
    cat > "$PLIST" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.vulturelabs.pilot-daemon</string>
    <key>ProgramArguments</key>
    <array>
        <string>${BIN_DIR}/pilot-daemon</string>
        <string>-registry</string>
        <string>${REGISTRY}</string>
        <string>-beacon</string>
        <string>${BEACON}</string>
        <string>-listen</string>
        <string>:4000</string>
        <string>-socket</string>
        <string>/tmp/pilot.sock</string>
        <string>-identity</string>
        <string>${PILOT_DIR}/identity.json</string>
        <string>-email</string>
        <string>${EMAIL}</string>
        <string>-encrypt</string>
${EXTRA_ARGS}    </array>
    <key>RunAtLoad</key>
    <false/>
    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>
    <key>StandardOutPath</key>
    <string>${PILOT_DIR}/daemon.log</string>
    <key>StandardErrorPath</key>
    <string>${PILOT_DIR}/daemon.log</string>
</dict>
</plist>
PLIST
    # Auto-updater LaunchAgent
    if [ -f "$BIN_DIR/pilot-updater" ]; then
        UPLIST="$PLIST_DIR/com.vulturelabs.pilot-updater.plist"
        cat > "$UPLIST" <<UPLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.vulturelabs.pilot-updater</string>
    <key>ProgramArguments</key>
    <array>
        <string>${BIN_DIR}/pilot-updater</string>
        <string>-install-dir</string>
        <string>${BIN_DIR}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>${PILOT_DIR}/updater.log</string>
    <key>StandardErrorPath</key>
    <string>${PILOT_DIR}/updater.log</string>
</dict>
</plist>
UPLIST
    fi

    echo "  Service: com.vulturelabs.pilot-daemon"
    echo "  Service: com.vulturelabs.pilot-updater (auto-updates)"
    echo "  Start:   launchctl load $PLIST"
    echo "  Stop:    launchctl unload $PLIST"
fi

# --- Add to PATH ---

IN_PATH=false
case ":$PATH:" in
    *":${BIN_DIR}:"*) IN_PATH=true ;;
esac

if [ "$IN_PATH" = false ]; then
    SHELL_NAME=$(basename "$SHELL" 2>/dev/null || echo "sh")
    case "$SHELL_NAME" in
        zsh)  RC="$HOME/.zshrc" ;;
        bash) RC="$HOME/.bashrc" ;;
        *)    RC="$HOME/.profile" ;;
    esac
    if [ -f "$RC" ] && grep -q "$BIN_DIR" "$RC" 2>/dev/null; then
        : # already in rc file
    else
        echo "" >> "$RC"
        echo "# Pilot Protocol" >> "$RC"
        echo "export PATH=\"${BIN_DIR}:\$PATH\"" >> "$RC"
        echo "  Added ${BIN_DIR} to PATH in ${RC}"
    fi
fi

# --- Verify ---

# Write version file for the auto-updater
[ -n "$TAG" ] && echo "$TAG" > "$BIN_DIR/.pilot-version"

echo ""
echo "Installed:"
echo "  pilot-daemon    ${BIN_DIR}/pilot-daemon"
echo "  pilotctl         ${BIN_DIR}/pilotctl"
echo "  pilot-gateway    ${BIN_DIR}/pilot-gateway"
echo "  pilot-updater    ${BIN_DIR}/pilot-updater (auto-updates in background)"
echo ""
echo "Config: ${PILOT_DIR}/config.json"
echo "  Registry: ${REGISTRY}"
echo "  Beacon:   ${BEACON}"
echo "  Socket:   /tmp/pilot.sock"
echo "  Identity: ${PILOT_DIR}/identity.json"
echo "  Email:    ${EMAIL}"
echo ""
echo "Get started:"
echo ""
echo "  export PATH=\"${BIN_DIR}:\$PATH\"    # if not restarting your shell"
echo "  pilotctl daemon start --hostname my-agent    # email already saved"
echo "  pilotctl info"
echo "  pilotctl ping <other-agent>"
echo ""
echo "Bridge IP traffic (requires root for ports < 1024):"
echo ""
echo "  sudo ${BIN_DIR}/pilotctl gateway start --ports 80,3000 <pilot-addr>"
echo "  curl http://10.4.0.1:3000/status"
echo ""
