#!/bin/bash
# GitHub SSH Key Oluşturma ve Kurulum Scripti
#
# HEADLESS: her soru bir env değişkeniyle önceden cevaplanabilir ve terminal
# yoksa script SORMAZ. Üç `read -p` koruma olmadan duruyordu; bir launchd
# ajanının ya da uzak bir kabuğun altında ilki sonsuza kadar bekler ve dışarı
# hiçbir şey yazmaz, yani kurulum "asılı kaldı" diye görünür. Bir sunucuda
# çalışması hedeflenen bir aracın sessizce beklemesi, açıkça reddetmesinden
# kötüdür.
#
#   MULTI_AGENT_UNATTENDED=1  terminal olsa bile soru sorulmaz
#   SSH_SETUP_EMAIL     anahtarın yorum alanına yazılacak e-posta (zorunlu)
#   SSH_SETUP_OVERWRITE e|h  - var olan anahtarın üzerine yazılsın mı (varsayılan h)
#   SSH_SETUP_TEST      e|h  - sonunda github.com'a bağlantı denensin mi (varsayılan h)

set -euo pipefail

# Soruyu sor, ama yalnız soracak birisi varsa. Terminal yoksa env'deki cevabı
# kullan; o da yoksa boş dön ve kararı çağırana bırak.
ask() {
    local prompt="$1" preset="$2" __var="$3" reply=""
    if [ -n "$preset" ]; then
        printf '%s%s [env]\n' "$prompt" "$preset"
        printf -v "$__var" '%s' "$preset"
        return 0
    fi
    # "Terminal yok" başsızlığın olağan biçimi, tek biçimi değil: screen,
    # tmux ya da bir sunucudaki login kabuğunun terminali VARDIR ve önünde
    # kimse yoktur. MULTI_AGENT_UNATTENDED=1 operatörün bunu açıkça söylemesi;
    # refs/unattended-contract.md. Tanımsızken hiçbir şey değişmez.
    if [ ! -t 0 ] || [ "${MULTI_AGENT_UNATTENDED:-}" = "1" ]; then
        printf -v "$__var" '%s' ""
        return 0
    fi
    # EOF (Ctrl-D) is an answer, not a crash: without `|| true` `set -e`
    # turns a user pressing Ctrl-D into an exit with no message at all.
    read -r -p "$prompt" reply || true
    printf -v "$__var" '%s' "$reply"
}

echo "=== GitHub SSH Key Kurulumu ==="
echo ""

# E-posta adresi al
ask "GitHub e-posta adresinizi girin: " "${SSH_SETUP_EMAIL:-}" EMAIL

if [ -z "$EMAIL" ]; then
    if [ -t 0 ] && [ "${MULTI_AGENT_UNATTENDED:-}" != "1" ]; then
        echo "Hata: E-posta adresi boş olamaz."
    else
        if [ "${MULTI_AGENT_UNATTENDED:-}" = "1" ]; then
            echo "Hata: MULTI_AGENT_UNATTENDED=1 ve SSH_SETUP_EMAIL tanımlı değil." >&2
        else
            echo "Hata: terminal yok ve SSH_SETUP_EMAIL tanımlı değil." >&2
        fi
        echo "      Başsız çalıştırmak için: SSH_SETUP_EMAIL=you@example.com $0" >&2
    fi
    exit 1
fi

# Key dosya adı
KEY_NAME="id_ed25519_github"
KEY_PATH="$HOME/.ssh/$KEY_NAME"

# .ssh klasörü yoksa oluştur
mkdir -p "$HOME/.ssh"
chmod 700 "$HOME/.ssh"

# Mevcut key kontrolü
if [ -f "$KEY_PATH" ]; then
    echo ""
    echo "Uyari: $KEY_PATH zaten mevcut."
    # Varsayılan HAYIR. Başsız bir koşuda cevapsız kalan bir "üzerine yazayım
    # mı" sorusunun güvenli tarafı, var olan anahtarı korumaktır.
    ask "Üzerine yazmak istiyor musunuz? (e/h): " "${SSH_SETUP_OVERWRITE:-}" OVERWRITE
    if [ "$OVERWRITE" != "e" ]; then
        echo "İşlem iptal edildi."
        exit 0
    fi
fi

# SSH key oluştur (Ed25519 - modern ve güvenli)
echo ""
echo "SSH key oluşturuluyor..."
# ssh-keygen var olan bir dosyayı görünce KENDİ "Overwrite (y/n)?" sorusunu
# sorar - yani yukarıdaki onayı geçtikten sonra başsız koşu ikinci bir
# soruda asılır. Onay zaten alındı; dosyayı önce kaldır.
rm -f "$KEY_PATH" "${KEY_PATH}.pub"
ssh-keygen -t ed25519 -C "$EMAIL" -f "$KEY_PATH" -N "" -q

echo ""
echo "SSH key başarıyla oluşturuldu!"

# SSH agent'a ekle
eval "$(ssh-agent -s)" > /dev/null 2>&1

# SSH config ayarla (UseKeychain yalnızca macOS'ta geçerli bir seçenek;
# Linux'ta ssh bilinmeyen seçenek diye config'i reddeder)
SSH_CONFIG="$HOME/.ssh/config"
USE_KEYCHAIN_LINE=""
if [ "$(uname -s 2>/dev/null)" = "Darwin" ]; then
    USE_KEYCHAIN_LINE="    UseKeychain yes"
fi
if ! grep -q "github.com" "$SSH_CONFIG" 2>/dev/null; then
    cat >> "$SSH_CONFIG" <<EOF

Host github.com
    HostName github.com
    User git
    IdentityFile $KEY_PATH
    AddKeysToAgent yes
${USE_KEYCHAIN_LINE}
EOF
    chmod 600 "$SSH_CONFIG"
    echo "SSH config güncellendi."
fi

# Key'i agent'a ekle (macOS Keychain ile)
# Agent yoksa ekleme başarısız olur; anahtar yazıldıktan sonra bunun için
# çıkmak, kurulumu yarıda bırakıp kullanıcıya hiçbir sonraki adımı
# göstermemek demek.
ssh-add --apple-use-keychain "$KEY_PATH" 2>/dev/null \
  || ssh-add "$KEY_PATH" 2>/dev/null \
  || echo "[Uyari: anahtar ssh-agent'a eklenemedi  -  elle: ssh-add $KEY_PATH]"

# Public key'i göster ve kopyala
echo ""
echo "================================================"
echo "  Public key'iniz (aşağıdaki GitHub'a eklenecek):"
echo "================================================"
echo ""
cat "${KEY_PATH}.pub"
echo ""

# Panoya kopyala
if command -v pbcopy >/dev/null 2>&1; then
  pbcopy < "${KEY_PATH}.pub"
  echo "[Otomatik olarak panoya kopyalandı!]"
elif command -v xclip >/dev/null 2>&1; then
  xclip -selection clipboard < "${KEY_PATH}.pub"
  echo "[Otomatik olarak panoya kopyalandı! (xclip)]"
else
  echo "[Panoya kopyalanamadı  -  yukarıdaki anahtarı manuel kopyalayın]"
fi

echo ""
echo "=== Sonraki Adımlar ==="
echo "1. https://github.com/settings/ssh/new adresine gidin"
echo "2. 'Title' alanına bir isim verin (ör: MacBook)"
echo "3. 'Key' alanına kopyalanan key'i yapıştırın (Cmd+V)"
echo "4. 'Add SSH key' butonuna tıklayın"
echo ""

# GitHub'a key eklendikten sonra test
ask "Key'i GitHub'a ekledikten sonra test etmek ister misiniz? (e/h): " "${SSH_SETUP_TEST:-}" TEST
if [ "$TEST" = "e" ]; then
    echo ""
    echo "GitHub bağlantısı test ediliyor..."
    # Bilinmeyen host anahtarı üçüncü bir interaktif soru demek; başsız
    # koşuda orada asılırdı.
    ssh -o StrictHostKeyChecking=accept-new -T git@github.com 2>&1 || true
fi

echo ""
echo "Tamamlandı!"
