#!/bin/bash
# =============================================================================
#  CellHub WebRTC Dialer — Magnus/Asterisk Sunucu Kurulum Scripti
#  Bu script müşterinin Magnus/Asterisk sunucusunda çalıştırılmalıdır.
#  Platform: https://autodialer.center
#  Janus Sunucu: 72.61.186.165
# =============================================================================

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

ok()   { echo -e "${GREEN}[✓]${NC} $1"; }
info() { echo -e "${BLUE}[i]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
err()  { echo -e "${RED}[✗]${NC} $1"; }
step() { echo -e "\n${CYAN}━━━ $1 ━━━${NC}"; }

# Root kontrolü
if [ "$EUID" -ne 0 ]; then
    err "Bu script root yetkisiyle çalıştırılmalıdır."
    echo "    Kullanım: sudo bash magnus_dialer_setup.sh"
    exit 1
fi

clear
echo -e "${CYAN}"
echo "  ╔══════════════════════════════════════════════════╗"
echo "  ║     CellHub WebRTC Dialer — Magnus Kurulum       ║"
echo "  ╚══════════════════════════════════════════════════╝"
echo -e "${NC}"
echo "  Bu script aşağıdaki işlemleri otomatik yapar:"
echo "  • sip.conf ayarlarını günceller (directmedia, nat, codec)"
echo "  • Firewall kurallarını ekler (SIP + RTP portları)"
echo "  • Asterisk'i yeniden yükler"
echo ""

# =============================================================================
# BİLGİ TOPLAMA
# =============================================================================
step "Gerekli Bilgiler"

# Janus/Dialer sunucu IP
while true; do
    read -p "  Janus/Dialer sunucu IP adresi (örn: 72.61.186.165): " JANUS_IP
    if [[ $JANUS_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        ok "Janus IP: $JANUS_IP"
        break
    else
        err "Geçersiz IP formatı, tekrar deneyin."
    fi
done

# Magnus/Asterisk sunucu public IP (NAT için)
while true; do
    # Otomatik tespit dene
    AUTO_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || curl -s --max-time 5 api.ipify.org 2>/dev/null)
    if [[ $AUTO_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        read -p "  Bu sunucunun public IP adresi [$AUTO_IP]: " ASTERISK_PUBLIC_IP
        ASTERISK_PUBLIC_IP=${ASTERISK_PUBLIC_IP:-$AUTO_IP}
    else
        read -p "  Bu sunucunun public IP adresi: " ASTERISK_PUBLIC_IP
    fi
    if [[ $ASTERISK_PUBLIC_IP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        ok "Asterisk public IP: $ASTERISK_PUBLIC_IP"
        break
    else
        err "Geçersiz IP formatı, tekrar deneyin."
    fi
done

# RTP port aralığı
read -p "  RTP port aralığı başlangıç [10000]: " RTP_START
RTP_START=${RTP_START:-10000}
read -p "  RTP port aralığı bitiş [20000]: " RTP_END
RTP_END=${RTP_END:-20000}
ok "RTP port aralığı: $RTP_START - $RTP_END"

# sip.conf konumu
SIP_CONF=""
for path in /etc/asterisk/sip.conf /usr/local/asterisk/etc/asterisk/sip.conf; do
    if [ -f "$path" ]; then
        SIP_CONF="$path"
        break
    fi
done

if [ -z "$SIP_CONF" ]; then
    read -p "  sip.conf dosya yolu: " SIP_CONF
fi

if [ ! -f "$SIP_CONF" ]; then
    err "sip.conf bulunamadı: $SIP_CONF"
    exit 1
fi
ok "sip.conf: $SIP_CONF"

# rtp.conf konumu
RTP_CONF=$(dirname "$SIP_CONF")/rtp.conf
ok "rtp.conf: $RTP_CONF"

echo ""
echo -e "${YELLOW}  Devam etmek istiyor musunuz? (e/h)${NC}"
read -p "  > " CONFIRM
if [[ ! $CONFIRM =~ ^[Ee]$ ]]; then
    echo "  İptal edildi."
    exit 0
fi

# =============================================================================
# YEDEK AL
# =============================================================================
step "Yedekleme"

BACKUP_DIR="/etc/asterisk/backup_dialer_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

cp "$SIP_CONF" "$BACKUP_DIR/sip.conf.bak"
ok "sip.conf yedeklendi → $BACKUP_DIR/sip.conf.bak"

if [ -f "$RTP_CONF" ]; then
    cp "$RTP_CONF" "$BACKUP_DIR/rtp.conf.bak"
    ok "rtp.conf yedeklendi"
fi

# =============================================================================
# SIP.CONF DÜZENLEME
# =============================================================================
step "sip.conf Ayarları"

# [general] bölümüne eklenecek ayarlar
# Her ayar: önce mevcut mi kontrol et, yoksa ekle, varsa güncelle

update_sip_conf() {
    local key="$1"
    local value="$2"
    local file="$SIP_CONF"

    # [general] bölümünde key=value var mı?
    if grep -q "^${key}\s*=" "$file"; then
        # Mevcut satırı güncelle
        sed -i "s|^${key}\s*=.*|${key}=${value}|" "$file"
        ok "$key=$value (güncellendi)"
    else
        # [general] bölümünün sonuna ekle
        sed -i "/^\[general\]/a ${key}=${value}" "$file"
        ok "$key=$value (eklendi)"
    fi
}

# directmedia=no — RTP Janus üzerinden gitsin, doğrudan tarayıcıya gitmesin
update_sip_conf "directmedia" "no"

# nat=yes — NAT arkasındaki istemciler için
update_sip_conf "nat" "yes"

# canreinvite=no — directmedia ile aynı işlev, eski Asterisk için
update_sip_conf "canreinvite" "no"

# externip — Asterisk'in SDP'de yayınlayacağı public IP
update_sip_conf "externip" "$ASTERISK_PUBLIC_IP"

# Codec ayarları — WebRTC destekli kodekler
# Önce mevcut disallow/allow satırlarını kaldır, temiz ekle
sed -i '/^disallow\s*=/d' "$SIP_CONF"
sed -i '/^allow\s*=\s*all/d' "$SIP_CONF"

# [general] altına codec ekle
sed -i "/^\[general\]/a allow=g722\nallow=alaw\nallow=ulaw\ndisallow=all" "$SIP_CONF"
ok "Codec ayarları: disallow=all, allow=ulaw/alaw/g722"

# rtptimeout — 0 = devre dışı (Janus bağlantısı kopmaları önler)
update_sip_conf "rtptimeout" "0"
update_sip_conf "rtpholdtimeout" "0"
update_sip_conf "rtpkeepalive" "30"

# Janus IP'ini trusted peer olarak ekle (varsa güncelle)
JANUS_PEER_BLOCK="
; === CellHub WebRTC Dialer — Janus Gateway ===
[janus-dialer]
type=peer
host=$JANUS_IP
nat=yes
directmedia=no
canreinvite=no
insecure=port,invite
qualify=yes
allow=ulaw
allow=alaw
allow=g722
; ============================================="

# Daha önce eklenmiş mi kontrol et
if grep -q "\[janus-dialer\]" "$SIP_CONF"; then
    warn "[janus-dialer] bölümü zaten mevcut, atlanıyor."
else
    echo "$JANUS_PEER_BLOCK" >> "$SIP_CONF"
    ok "[janus-dialer] peer eklendi"
fi

# =============================================================================
# RTP.CONF DÜZENLEME
# =============================================================================
step "rtp.conf Ayarları"

if [ -f "$RTP_CONF" ]; then
    # Mevcut port ayarını güncelle
    if grep -q "^rtpstart\s*=" "$RTP_CONF"; then
        sed -i "s|^rtpstart\s*=.*|rtpstart=$RTP_START|" "$RTP_CONF"
    else
        echo "rtpstart=$RTP_START" >> "$RTP_CONF"
    fi
    if grep -q "^rtpend\s*=" "$RTP_CONF"; then
        sed -i "s|^rtpend\s*=.*|rtpend=$RTP_END|" "$RTP_CONF"
    else
        echo "rtpend=$RTP_END" >> "$RTP_CONF"
    fi
    ok "RTP port aralığı: $RTP_START-$RTP_END"
else
    # rtp.conf yoksa oluştur
    cat > "$RTP_CONF" <<EOF
[general]
rtpstart=$RTP_START
rtpend=$RTP_END
EOF
    ok "rtp.conf oluşturuldu"
fi

# =============================================================================
# FIREWALL KURALLARI
# =============================================================================
step "Firewall Ayarları"

add_fw_rule() {
    local proto="$1" port="$2" comment="$3"
    if command -v ufw &>/dev/null && ufw status | grep -q "active"; then
        ufw allow from "$JANUS_IP" to any port "$port" proto "$proto" comment "$comment" &>/dev/null
        ok "UFW: $JANUS_IP → $port/$proto ($comment)"
    elif command -v iptables &>/dev/null; then
        # Kural zaten varsa ekleme
        if ! iptables -C INPUT -s "$JANUS_IP" -p "$proto" --dport "$port" -j ACCEPT &>/dev/null; then
            iptables -I INPUT -s "$JANUS_IP" -p "$proto" --dport "$port" -j ACCEPT
            ok "iptables: $JANUS_IP → $port/$proto ($comment)"
        else
            warn "iptables kuralı zaten mevcut: $port/$proto"
        fi
    else
        warn "Firewall aracı bulunamadı. Manuel ekleyin: $JANUS_IP → $port/$proto"
    fi
}

# SIP port
add_fw_rule "udp" "5060" "SIP-Janus"
add_fw_rule "tcp" "5060" "SIP-Janus-TCP"

# RTP port aralığı
if command -v ufw &>/dev/null && ufw status | grep -q "active"; then
    ufw allow from "$JANUS_IP" to any port "${RTP_START}:${RTP_END}" proto udp comment "RTP-Janus" &>/dev/null
    ok "UFW: $JANUS_IP → $RTP_START:$RTP_END/udp (RTP)"
elif command -v iptables &>/dev/null; then
    if ! iptables -C INPUT -s "$JANUS_IP" -p udp --dport "${RTP_START}:${RTP_END}" -j ACCEPT &>/dev/null; then
        iptables -I INPUT -s "$JANUS_IP" -p udp --dport "${RTP_START}:${RTP_END}" -j ACCEPT
        ok "iptables: $JANUS_IP → $RTP_START:$RTP_END/udp (RTP)"
    else
        warn "RTP iptables kuralı zaten mevcut"
    fi
fi

# iptables kalıcı kaydet
if command -v iptables-save &>/dev/null; then
    if command -v netfilter-persistent &>/dev/null; then
        netfilter-persistent save &>/dev/null
        ok "iptables kuralları kalıcı kaydedildi (netfilter-persistent)"
    elif [ -f /etc/iptables/rules.v4 ]; then
        iptables-save > /etc/iptables/rules.v4
        ok "iptables kuralları kaydedildi → /etc/iptables/rules.v4"
    fi
fi

# =============================================================================
# ASTERİSK YENİDEN YÜKLE
# =============================================================================
step "Asterisk Yeniden Yükleme"

if command -v asterisk &>/dev/null; then
    asterisk -rx "sip reload" &>/dev/null
    sleep 2
    ok "Asterisk SIP modülü yeniden yüklendi"

    # Bağlantı kontrolü
    PEER_STATUS=$(asterisk -rx "sip show peers" 2>/dev/null | grep -c "OK\|Registered" || echo "0")
    info "Aktif SIP peer sayısı: $PEER_STATUS"
else
    err "asterisk komutu bulunamadı. Sunucu üzerinde Asterisk kurulu mu?"
fi

# =============================================================================
# SONUÇ
# =============================================================================
echo ""
echo -e "${GREEN}"
echo "  ╔══════════════════════════════════════════════════╗"
echo "  ║              Kurulum Tamamlandı!                 ║"
echo "  ╚══════════════════════════════════════════════════╝"
echo -e "${NC}"
echo -e "  ${GREEN}Yapılan değişiklikler:${NC}"
echo "  • sip.conf: directmedia=no, nat=yes, rtptimeout=0"
echo "  • sip.conf: Codec ulaw/alaw/g722 aktif"
echo "  • sip.conf: [janus-dialer] peer eklendi"
echo "  • rtp.conf: Port aralığı $RTP_START-$RTP_END"
echo "  • Firewall: $JANUS_IP için SIP+RTP izni"
echo ""
echo -e "  ${YELLOW}Yedekler:${NC} $BACKUP_DIR"
echo ""
echo -e "  ${CYAN}Test için:${NC}"
echo "  asterisk -rx \"sip show peers\""
echo "  asterisk -rx \"sip set debug on\""
echo ""

# =============================================================================
# MAGNUS DB KAYDI — CLI Change Özelliği
# =============================================================================
step "Magnus DB CLI Change Kaydı"

echo ""
read -p "  CLI Change özelliğini etkinleştirmek ister misiniz? (e/h): " CLI_CONFIRM
if [[ $CLI_CONFIRM =~ ^[Ee]$ ]]; then

    # Setup token al
    read -p "  Platform setup token'ınızı girin: " SETUP_TOKEN
    if [ -z "$SETUP_TOKEN" ]; then
        warn "Setup token girilmedi, CLI Change kaydı atlandı."
    else
        # Magnus DB bilgilerini res_config_mysql.conf'tan otomatik oku
        MYSQL_CONF="/etc/asterisk/res_config_mysql.conf"
        if [ -f "$MYSQL_CONF" ]; then
            DB_HOST_AUTO=$(grep '^dbhost' "$MYSQL_CONF" | awk -F'=' '{print $2}' | tr -d ' ')
            DB_NAME_AUTO=$(grep '^dbname' "$MYSQL_CONF" | awk -F'=' '{print $2}' | tr -d ' ')
            DB_USER_AUTO=$(grep '^dbuser' "$MYSQL_CONF" | awk -F'=' '{print $2}' | tr -d ' ')
            DB_PASS_AUTO=$(grep '^dbpass' "$MYSQL_CONF" | awk -F'=' '{print $2}' | tr -d ' ')
            info "Otomatik tespit edildi: $DB_USER_AUTO@$DB_HOST_AUTO/$DB_NAME_AUTO"
        fi

        # Kullanıcı onayı veya manuel giriş
        read -p "  Magnus DB host [$DB_HOST_AUTO]: " DB_HOST
        DB_HOST=${DB_HOST:-$DB_HOST_AUTO}
        read -p "  Magnus DB port [3306]: " DB_PORT
        DB_PORT=${DB_PORT:-3306}
        read -p "  Magnus DB user [autodialer_cli]: " DB_USER
        DB_USER=${DB_USER:-autodialer_cli}
        read -sp "  Magnus DB password: " DB_PASS
        echo ""
        read -p "  Magnus DB name [mbilling]: " DB_NAME
        DB_NAME=${DB_NAME:-mbilling}

        # autodialer_cli kullanıcısını oluştur (system mysql user ile)
        info "autodialer_cli MySQL kullanıcısı oluşturuluyor..."
        SQL="CREATE USER IF NOT EXISTS '${DB_USER}'@'72.61.186.165' IDENTIFIED BY '${DB_PASS}'; GRANT SELECT, UPDATE ON ${DB_NAME}.pkg_sip TO '${DB_USER}'@'72.61.186.165'; FLUSH PRIVILEGES;"
        if su -s /bin/bash mysql -c "mysql ${DB_NAME} -e \"${SQL}\"" 2>/dev/null; then
            ok "autodialer_cli kullanıcısı oluşturuldu"
        elif mysql -u root -e "${SQL}" 2>/dev/null; then
            ok "autodialer_cli kullanıcısı oluşturuldu (root ile)"
        else
            warn "Kullanıcı otomatik oluşturulamadı. MySQL'de manuel çalıştırın:"
            echo "    CREATE USER '${DB_USER}'@'72.61.186.165' IDENTIFIED BY '${DB_PASS}';"
            echo "    GRANT SELECT, UPDATE ON ${DB_NAME}.pkg_sip TO '${DB_USER}'@'72.61.186.165';"
            echo "    FLUSH PRIVILEGES;"
        fi

        # Platform'a kaydet
        info "autodialer.center'a Magnus DB bilgileri kaydediliyor..."
        RESPONSE=$(curl -s -X POST "https://autodialer.center/register_magnus.php" \
            -d "setup_token=$SETUP_TOKEN" \
            -d "magnus_db_host=$DB_HOST" \
            -d "magnus_db_port=$DB_PORT" \
            -d "magnus_db_user=$DB_USER" \
            -d "magnus_db_pass=$DB_PASS" \
            -d "magnus_db_name=$DB_NAME" \
            --max-time 10 2>/dev/null)

        if echo "$RESPONSE" | grep -q '"ok":true'; then
            ok "Magnus DB kaydı başarılı! CLI Change özelliği aktif."
        else
            err "Kayıt başarısız: $RESPONSE"
            warn "Setup token'ınızı ve bilgileri kontrol edin."
        fi
    fi
else
    info "CLI Change kaydı atlandı."
fi
