#!/bin/bash

# Tüm arşivleme formatlarını destekleyen yedekleme betiği
# Yazar: @erhodev
# Tarih: 2025-05-03

# Renk tanımlamaları
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # Renksiz

# Kullanım bilgisini göster
function show_usage {
    echo -e "${YELLOW}Kullanım:${NC}"
    echo -e "  $0 <kaynak_dizin> [hedef_dizin] [arşiv_formatı] [sıkıştırma_seviyesi]"
    echo
    echo -e "${YELLOW}Parametreler:${NC}"
    echo -e "  kaynak_dizin      - Yedeklemek istediğiniz klasörün yolu"
    echo -e "  hedef_dizin       - İsteğe bağlı: Yedeğin kaydedileceği dizin (Varsayılan: mevcut dizin)"
    echo -e "  arşiv_formatı     - İsteğe bağlı: Arşivleme için kullanılacak format (Varsayılan: zip)"
    echo -e "                      Desteklenen formatlar: zip, tar, targz, tarbz2, tarxz, 7z"
    echo -e "  sıkıştırma_seviyesi - İsteğe bağlı: 0-9 arası sıkıştırma seviyesi (Varsayılan: 5)"
    echo
    echo -e "${YELLOW}Örnekler:${NC}"
    echo -e "  $0 /home/kullanici/belgelerim"
    echo -e "  $0 /home/kullanici/projeler /media/yedek targz"
    echo -e "  $0 /home/kullanici/fotograflar /media/yedek zip 9"
    echo
}

# Program çağrılma şeklini kontrol et
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    show_usage
    exit 0
fi

# Parametreleri doğrula
if [ -z "$1" ]; then
    echo -e "${RED}Hata: Kaynak dizin parametresi eksik.${NC}"
    show_usage
    exit 1
fi

# Kaynak dizini ayarla
SOURCE_DIR="$1"

# Kaynak dizinin varlığını kontrol et
if [ ! -d "$SOURCE_DIR" ]; then
    echo -e "${RED}Hata: Kaynak dizin '$SOURCE_DIR' bulunamadı veya bir dizin değil.${NC}"
    exit 2
fi

# Hedef dizini ayarla (verilmemişse mevcut dizin)
if [ -z "$2" ]; then
    DEST_DIR="$(pwd)"
else
    DEST_DIR="$2"
    # Hedef dizin yoksa oluştur
    if [ ! -d "$DEST_DIR" ]; then
        mkdir -p "$DEST_DIR"
        if [ $? -ne 0 ]; then
            echo -e "${RED}Hata: Hedef dizin '$DEST_DIR' oluşturulamadı.${NC}"
            exit 3
        fi
    fi
fi

# Arşiv formatını ayarla (verilmemişse zip)
if [ -z "$3" ]; then
    ARCHIVE_FORMAT="zip"
else
    ARCHIVE_FORMAT="$3"
fi

# Sıkıştırma seviyesini ayarla (verilmemişse 5)
if [ -z "$4" ]; then
    COMPRESSION_LEVEL=5
else
    if [[ "$4" =~ ^[0-9]$ ]]; then
        COMPRESSION_LEVEL="$4"
    else
        echo -e "${RED}Hata: Sıkıştırma seviyesi 0-9 arasında bir sayı olmalıdır.${NC}"
        exit 4
    fi
fi

# Zaman damgası oluştur ve dosya adı belirle
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
SOURCE_DIR_NAME=$(basename "$SOURCE_DIR")

# Gerekli paketleri kontrol et ve yükle
function check_install_package {
    local package=$1
    if ! command -v "$package" &> /dev/null; then
        echo -e "${YELLOW}Uyarı: $package komutu bulunamadı. Yüklemeye çalışılıyor...${NC}"
        sudo apt-get update && sudo apt-get install -y "$package"
        if [ $? -ne 0 ]; then
            echo -e "${RED}Hata: $package yüklenemedi. Lütfen 'sudo apt-get install $package' komutu ile manuel olarak yükleyin.${NC}"
            exit 5
        fi
    fi
}

# Ana arşivleme fonksiyonu
function create_archive {
    local format=$1
    local source=$2
    local dest=$3
    local level=$4
    local timestamp=$5
    local source_name=$6

    case "$format" in
        zip)
            check_install_package "zip"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.zip"
            echo -e "${CYAN}$level seviyesinde ZIP arşivi oluşturuluyor (tüm izinler korunacak)...${NC}"
            cd "$(dirname "$source")" || exit 6
            # -r: recursive, -p: izinleri koru, -{level}: sıkıştırma seviyesi
            zip -r -p "-${level}" "$ARCHIVE_PATH" "$(basename "$source")"
            verify_command="zip -T"
            ;;
        tar)
            check_install_package "tar"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.tar"
            echo -e "${CYAN}TAR arşivi oluşturuluyor (tüm izinler korunacak)...${NC}"
            # -p: izinleri koru, --preserve-permissions: izinleri koru, --same-owner: sahipliği koru
            tar --preserve-permissions --same-owner -cf "$ARCHIVE_PATH" -C "$(dirname "$source")" "$(basename "$source")"
            verify_command="tar -tf"
            ;;
        targz)
            check_install_package "tar"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.tar.gz"
            echo -e "${CYAN}$level seviyesinde TAR.GZ arşivi oluşturuluyor (tüm izinler korunacak)...${NC}"
            # -p: izinleri koru, --preserve-permissions: izinleri koru, --same-owner: sahipliği koru
            GZIP="-$level" tar --preserve-permissions --same-owner -czf "$ARCHIVE_PATH" -C "$(dirname "$source")" "$(basename "$source")"
            verify_command="tar -tzf"
            ;;
        tarbz2)
            check_install_package "tar"
            check_install_package "bzip2"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.tar.bz2"
            echo -e "${CYAN}$level seviyesinde TAR.BZ2 arşivi oluşturuluyor (tüm izinler korunacak)...${NC}"
            # -p: izinleri koru, --preserve-permissions: izinleri koru, --same-owner: sahipliği koru
            BZIP2="-$level" tar --preserve-permissions --same-owner -cjf "$ARCHIVE_PATH" -C "$(dirname "$source")" "$(basename "$source")"
            verify_command="tar -tjf"
            ;;
        tarxz)
            check_install_package "tar"
            check_install_package "xz-utils"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.tar.xz"
            echo -e "${CYAN}$level seviyesinde TAR.XZ arşivi oluşturuluyor (tüm izinler korunacak)...${NC}"
            # -p: izinleri koru, --preserve-permissions: izinleri koru, --same-owner: sahipliği koru
            XZ_OPT="-${level}" tar --preserve-permissions --same-owner -cJf "$ARCHIVE_PATH" -C "$(dirname "$source")" "$(basename "$source")"
            verify_command="tar -tJf"
            ;;
        7z)
            check_install_package "p7zip-full"
            ARCHIVE_PATH="${dest}/${source_name}_yedek_${timestamp}.7z"
            echo -e "${CYAN}$level seviyesinde 7Z arşivi oluşturuluyor...${NC}"
            # 7z için özel izin koruma parametreleri
            7z a -mx="$level" -ssw -snl "$ARCHIVE_PATH" "$source"
            verify_command="7z t"
            ;;
        *)
            echo -e "${RED}Hata: '$format' desteklenmeyen bir arşiv formatı.${NC}"
            echo -e "${YELLOW}Desteklenen formatlar: zip, tar, targz, tarbz2, tarxz, 7z${NC}"
            exit 7
            ;;
    esac

    # Arşiv başarıyla oluşturuldu mu kontrol et
    if [ $? -eq 0 ]; then
        ARCHIVE_SIZE=$(du -h "$ARCHIVE_PATH" | cut -f1)
        echo -e "${GREEN}Yedekleme başarıyla tamamlandı!${NC}"
        echo -e "Yedek kaydedildi: ${ARCHIVE_PATH}"
        echo -e "Yedek boyutu: ${ARCHIVE_SIZE}"

        # Arşivin bütünlüğünü doğrula
        echo -e "${YELLOW}Arşiv bütünlüğü doğrulanıyor...${NC}"
        $verify_command "$ARCHIVE_PATH" > /dev/null

        if [ $? -eq 0 ]; then
            echo -e "${GREEN}Arşiv başarıyla doğrulandı!${NC}"
        else
            echo -e "${RED}Uyarı: Arşiv doğrulama başarısız oldu. Yedek bozulmuş olabilir.${NC}"
            exit 8
        fi
    else
        echo -e "${RED}Hata: Yedekleme başarısız oldu. İzinleri ve kullanılabilir disk alanını kontrol edin.${NC}"
        exit 9
    fi

    return 0
}

# Arşiv bilgilerini görüntüle
echo -e "${GREEN}=== Yedekleme Bilgileri ===${NC}"
echo -e "${BLUE}Kaynak:${NC} $SOURCE_DIR"
echo -e "${BLUE}Hedef:${NC} $DEST_DIR"
echo -e "${BLUE}Arşiv Formatı:${NC} $ARCHIVE_FORMAT"
echo -e "${BLUE}Sıkıştırma Seviyesi:${NC} $COMPRESSION_LEVEL"
echo -e "${BLUE}Zaman Damgası:${NC} $TIMESTAMP"

# Kaynak klasörün boyutunu hesapla
SOURCE_SIZE=$(du -sh "$SOURCE_DIR" | cut -f1)
echo -e "${BLUE}Kaynak Boyutu:${NC} $SOURCE_SIZE"
echo -e "${GREEN}=========================${NC}"

# Arşivi oluştur
echo -e "${MAGENTA}Yedekleme işlemi başlatılıyor...${NC}"
create_archive "$ARCHIVE_FORMAT" "$SOURCE_DIR" "$DEST_DIR" "$COMPRESSION_LEVEL" "$TIMESTAMP" "$SOURCE_DIR_NAME"

echo -e "${GREEN}Tüm işlemler başarıyla tamamlandı.${NC}"
exit 0