#!/usr/bin/env bash
# onx-backup-destination-test — Yedek hedefine bağlantı ve yazma testi
#
# Input:  {"type":"local|s3|wasabi|backblaze_b2|sftp|ftp|restic", "config":{...}}
# Output: {"reachable":true, "writeable":true, "latency_ms":42, "free_space_mb":50000}
#
# exit codes: 0=ok 1=bad input 2=preflight 3=connection failed

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/_lib/common.sh"

require_root
onx_json_input

TYPE="$(onx_json_field type)"
CONFIG="$(echo "$INPUT" | jq -c '.config // {}')"

[[ -z "$TYPE" ]] && onx_die 1 "type alanı zorunlu"

onx_log "backup-destination-test: type=${TYPE}"

START_NS=$(date +%s%N 2>/dev/null || echo 0)

_elapsed_ms() {
    local end_ns
    end_ns=$(date +%s%N 2>/dev/null || echo 0)
    echo $(( (end_ns - START_NS) / 1000000 ))
}

case "$TYPE" in
# ─── Local ────────────────────────────────────────────────────────────────────
local)
    PATH_VAL="$(onx_json_get "$CONFIG" path '/var/backups/onox')"
    [[ -z "$PATH_VAL" ]] && onx_die 1 "config.path zorunlu"

    # Safety (DEEP-09): yalnız /var/backups/onox veya /mnt/backup ALTINDA. Prefix-match
    # değil — realpath -m ile kanonikleştir + sınır kontrolü ('/var/backups/onoxevil'
    # kardeş-prefix'i ve symlink kaçışını engelle).
    PATH_REAL="$(realpath -m "$PATH_VAL" 2>/dev/null || printf '%s' "$PATH_VAL")"
    case "$PATH_REAL" in
        /var/backups/onox|/var/backups/onox/*|/mnt/backup|/mnt/backup/*) : ;;
        *) onx_die 1 "Güvensiz path: ${PATH_VAL}" ;;
    esac
    PATH_VAL="$PATH_REAL"

    mkdir -p "$PATH_VAL" 2>/dev/null || onx_die 2 "Dizin oluşturulamadı: ${PATH_VAL}"

    # Write test
    TEST_FILE="${PATH_VAL}/.onx_write_test_$$"
    echo "onox-test" > "$TEST_FILE" 2>/dev/null || onx_die 3 "Yazma testi başarısız: ${PATH_VAL}"
    rm -f "$TEST_FILE"

    # Free space in MB
    FREE_MB=$(df -m "$PATH_VAL" 2>/dev/null | awk 'NR==2 {print $4}' || echo 0)
    LAT=$(_elapsed_ms)

    onx_json_out reachable true writeable true latency_ms "$LAT" free_space_mb "$FREE_MB"
    ;;

# ─── S3 / Wasabi ──────────────────────────────────────────────────────────────
s3|wasabi)
    require_cmd aws

    ENDPOINT="$(onx_json_get "$CONFIG" endpoint '')"
    BUCKET="$(onx_json_get "$CONFIG" bucket '')"
    REGION="$(onx_json_get "$CONFIG" region 'us-east-1')"
    ACCESS_KEY="$(onx_json_get "$CONFIG" access_key '')"
    SECRET_KEY="$(onx_json_get "$CONFIG" secret_key '')"

    [[ -z "$BUCKET" ]]     && onx_die 1 "config.bucket zorunlu"
    [[ -z "$ACCESS_KEY" ]] && onx_die 1 "config.access_key zorunlu"
    [[ -z "$SECRET_KEY" ]] && onx_die 1 "config.secret_key zorunlu"

    ENDPOINT_ARG=""
    [[ -n "$ENDPOINT" ]] && ENDPOINT_ARG="--endpoint-url=${ENDPOINT}"

    AWS_ACCESS_KEY_ID="$ACCESS_KEY" \
    AWS_SECRET_ACCESS_KEY="$SECRET_KEY" \
    AWS_DEFAULT_REGION="$REGION" \
    aws s3 ls "s3://${BUCKET}" $ENDPOINT_ARG --no-sign-request 2>/dev/null \
        || AWS_ACCESS_KEY_ID="$ACCESS_KEY" \
           AWS_SECRET_ACCESS_KEY="$SECRET_KEY" \
           AWS_DEFAULT_REGION="$REGION" \
           aws s3 ls "s3://${BUCKET}" $ENDPOINT_ARG >/dev/null 2>&1 \
        || onx_die 3 "S3 bucket erişimi başarısız: ${BUCKET}"

    # Write test: tiny object
    TEST_KEY=".onox-test-$(date +%s)"
    AWS_ACCESS_KEY_ID="$ACCESS_KEY" \
    AWS_SECRET_ACCESS_KEY="$SECRET_KEY" \
    AWS_DEFAULT_REGION="$REGION" \
    aws s3 cp - "s3://${BUCKET}/${TEST_KEY}" $ENDPOINT_ARG <<< "onox-test" >/dev/null 2>&1 \
        && AWS_ACCESS_KEY_ID="$ACCESS_KEY" \
           AWS_SECRET_ACCESS_KEY="$SECRET_KEY" \
           AWS_DEFAULT_REGION="$REGION" \
           aws s3 rm "s3://${BUCKET}/${TEST_KEY}" $ENDPOINT_ARG >/dev/null 2>&1
    WRITEABLE=$([[ $? -eq 0 ]] && echo true || echo false)

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable "$WRITEABLE" latency_ms "$LAT"
    ;;

# ─── Backblaze B2 ─────────────────────────────────────────────────────────────
backblaze_b2)
    # B2 exposes an S3-compatible API — use aws CLI with custom endpoint
    require_cmd aws

    ENDPOINT="$(onx_json_get "$CONFIG" endpoint '')"
    REGION="$(onx_json_get "$CONFIG" region 'us-west-002')"
    BUCKET="$(onx_json_get "$CONFIG" bucket '')"
    APP_KEY_ID="$(onx_json_get "$CONFIG" application_key_id '')"
    APP_KEY="$(onx_json_get "$CONFIG" application_key '')"

    [[ -z "$BUCKET" ]]    && onx_die 1 "config.bucket zorunlu"
    [[ -z "$APP_KEY_ID" ]] && onx_die 1 "config.application_key_id zorunlu"
    [[ -z "$APP_KEY" ]]   && onx_die 1 "config.application_key zorunlu"

    [[ -z "$ENDPOINT" ]] && ENDPOINT="https://s3.${REGION}.backblazeb2.com"

    AWS_ACCESS_KEY_ID="$APP_KEY_ID" \
    AWS_SECRET_ACCESS_KEY="$APP_KEY" \
    AWS_DEFAULT_REGION="$REGION" \
    aws s3 ls "s3://${BUCKET}" --endpoint-url="$ENDPOINT" >/dev/null 2>&1 \
        || onx_die 3 "B2 bucket erişimi başarısız: ${BUCKET}"

    # Write test
    TEST_KEY=".onox-test-$(date +%s)"
    AWS_ACCESS_KEY_ID="$APP_KEY_ID" \
    AWS_SECRET_ACCESS_KEY="$APP_KEY" \
    AWS_DEFAULT_REGION="$REGION" \
    aws s3 cp - "s3://${BUCKET}/${TEST_KEY}" --endpoint-url="$ENDPOINT" <<< "onox-test" >/dev/null 2>&1 \
        && AWS_ACCESS_KEY_ID="$APP_KEY_ID" \
           AWS_SECRET_ACCESS_KEY="$APP_KEY" \
           AWS_DEFAULT_REGION="$REGION" \
           aws s3 rm "s3://${BUCKET}/${TEST_KEY}" --endpoint-url="$ENDPOINT" >/dev/null 2>&1
    WRITEABLE=$([[ $? -eq 0 ]] && echo true || echo false)

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable "$WRITEABLE" latency_ms "$LAT"
    ;;

# ─── SFTP ─────────────────────────────────────────────────────────────────────
sftp)
    require_cmd ssh

    HOST="$(onx_json_get "$CONFIG" host '')"
    PORT="$(onx_json_get "$CONFIG" port '22')"
    USER="$(onx_json_get "$CONFIG" username '')"
    PRIV_KEY="$(onx_json_get "$CONFIG" private_key '')"
    PASSWORD="$(onx_json_get "$CONFIG" password '')"
    REMOTE_PATH="$(onx_json_get "$CONFIG" remote_path '/backup')"

    [[ -z "$HOST" ]] && onx_die 1 "config.host zorunlu"
    [[ -z "$USER" ]] && onx_die 1 "config.username zorunlu"

    SSH_OPTS=(-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o BatchMode=yes -p "$PORT")

    if [[ -n "$PRIV_KEY" ]]; then
        # Write key to temp file
        TMP_KEY=$(mktemp /tmp/onx-sftp-key-XXXXXX)
        chmod 600 "$TMP_KEY"
        printf '%s\n' "$PRIV_KEY" > "$TMP_KEY"
        SSH_OPTS+=(-i "$TMP_KEY")
        trap 'rm -f "$TMP_KEY"' EXIT

        ssh "${SSH_OPTS[@]}" "${USER}@${HOST}" \
            "mkdir -p '${REMOTE_PATH}' && echo onox-test > '${REMOTE_PATH}/.onx_test_$$' && rm -f '${REMOTE_PATH}/.onx_test_$$'" 2>/dev/null \
            || onx_die 3 "SFTP bağlantısı başarısız: ${USER}@${HOST}:${PORT}"
    else
        require_cmd sshpass
        [[ -z "$PASSWORD" ]] && onx_die 1 "config.private_key veya config.password gerekli"

        sshpass -p "$PASSWORD" ssh "${SSH_OPTS[@]}" "${USER}@${HOST}" \
            "mkdir -p '${REMOTE_PATH}' && echo onox-test > '${REMOTE_PATH}/.onx_test_$$' && rm -f '${REMOTE_PATH}/.onx_test_$$'" 2>/dev/null \
            || onx_die 3 "SFTP bağlantısı başarısız: ${USER}@${HOST}:${PORT}"
    fi

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable true latency_ms "$LAT"
    ;;

# ─── FTP ──────────────────────────────────────────────────────────────────────
ftp)
    require_cmd lftp

    HOST="$(onx_json_get "$CONFIG" host '')"
    PORT="$(onx_json_get "$CONFIG" port '21')"
    USER="$(onx_json_get "$CONFIG" username '')"
    PASS="$(onx_json_get "$CONFIG" password '')"
    REMOTE_PATH="$(onx_json_get "$CONFIG" remote_path '/backup')"
    PASSIVE="$(onx_json_get "$CONFIG" passive 'true')"

    [[ -z "$HOST" ]] && onx_die 1 "config.host zorunlu"
    [[ -z "$USER" ]] && onx_die 1 "config.username zorunlu"
    [[ -z "$PASS" ]] && onx_die 1 "config.password zorunlu"

    PASSIVE_SETTING="set ftp:passive-mode yes"
    [[ "$PASSIVE" == "false" ]] && PASSIVE_SETTING="set ftp:passive-mode no"

    LFTP_PASSWORD="$PASS" lftp -u "$USER" --env-password "ftp://${HOST}:${PORT}" <<EOF 2>/dev/null
$PASSIVE_SETTING
set ftp:ssl-allow yes
mkdir -p ${REMOTE_PATH}
put /dev/null -o ${REMOTE_PATH}/.onx_test_$$
rm ${REMOTE_PATH}/.onx_test_$$
quit
EOF
    [[ $? -ne 0 ]] && onx_die 3 "FTP bağlantısı başarısız: ${USER}@${HOST}:${PORT}"

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable true latency_ms "$LAT"
    ;;

# ─── Restic ───────────────────────────────────────────────────────────────────
restic)
    require_cmd restic

    REPO="$(onx_json_get "$CONFIG" repo '')"
    PASS="$(onx_json_get "$CONFIG" password '')"

    [[ -z "$REPO" ]] && onx_die 1 "config.repo zorunlu"
    [[ -z "$PASS" ]] && onx_die 1 "config.password zorunlu"

    export RESTIC_PASSWORD="$PASS"
    # Depo erişilebilir mi? snapshots OK → hazır. Değilse init dene (yeni depoyu oluştur →
    # ilk push beklemeden çalışır). İkisi de olmazsa erişim/şifre sorunu.
    if ! restic -r "$REPO" snapshots >/dev/null 2>&1; then
        restic -r "$REPO" init >/dev/null 2>&1 \
            || onx_die 3 "Restic repo erişimi/başlatması başarısız: ${REPO}"
    fi

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable true latency_ms "$LAT"
    ;;

# ─── Google Drive (rclone, OAuth) ──────────────────────────────────────────────
google_drive)
    command -v rclone >/dev/null 2>&1 \
        || onx_die 2 "rclone kurulu değil — Google Drive için gerekli (curl https://rclone.org/install.sh | sudo bash)"

    CLIENT_ID="$(onx_json_get "$CONFIG" client_id '')"
    CLIENT_SECRET="$(onx_json_get "$CONFIG" client_secret '')"
    REFRESH_TOKEN="$(onx_json_get "$CONFIG" refresh_token '')"
    FOLDER_ID="$(onx_json_get "$CONFIG" folder_id '')"

    [[ -z "$CLIENT_ID" ]]     && onx_die 1 "config.client_id zorunlu"
    [[ -z "$CLIENT_SECRET" ]] && onx_die 1 "config.client_secret zorunlu"
    [[ -z "$REFRESH_TOKEN" ]] && onx_die 1 "config.refresh_token zorunlu"

    TOKEN_JSON="$(jq -nc --arg rt "$REFRESH_TOKEN" \
        '{access_token:"",token_type:"Bearer",refresh_token:$rt,expiry:"2000-01-01T00:00:00Z"}')"
    export RCLONE_CONFIG_GDRIVE_TYPE="drive"
    export RCLONE_CONFIG_GDRIVE_SCOPE="drive"
    export RCLONE_CONFIG_GDRIVE_CLIENT_ID="$CLIENT_ID"
    export RCLONE_CONFIG_GDRIVE_CLIENT_SECRET="$CLIENT_SECRET"
    export RCLONE_CONFIG_GDRIVE_TOKEN="$TOKEN_JSON"

    # folder_id alanı: gerçek Drive ID (uzun, 20+ [A-Za-z0-9_-]) → root_folder_id;
    # AKSİ HALDE klasör ADI kabul edilir → rclone path olarak verilir (gdrive:Ad/),
    # rclone klasörü kendisi OLUŞTURUR. Boşsa kök. (Kullanıcı "ONOXSOFT" gibi ad
    # yazınca eskiden geçersiz root_folder_id olup lsd patlıyordu.)
    GD_PATH=""
    if [[ -n "$FOLDER_ID" ]]; then
        if [[ "$FOLDER_ID" =~ ^[A-Za-z0-9_-]{20,}$ ]]; then
            export RCLONE_CONFIG_GDRIVE_ROOT_FOLDER_ID="$FOLDER_ID"
        else
            GD_PATH="$(printf '%s' "$FOLDER_ID" | tr -cd 'A-Za-z0-9 ._-')"
        fi
    fi

    # Auth doğrula (lsd kök) + hedefe küçük dosya yaz/sil (klasör adıysa oluşturulur).
    TMP_T="$(mktemp /tmp/onx-gdrive-test-XXXXXX)"
    echo "onox-test" > "$TMP_T"
    trap 'rm -f "$TMP_T"' EXIT

    GD_ERR="$(rclone lsd "gdrive:" 2>&1 >/dev/null)" \
        || onx_die 3 "Drive erişimi başarısız (auth/refresh_token): ${GD_ERR:0:200}"
    WT="gdrive:${GD_PATH:+$GD_PATH/}.onx_write_test_$$"
    GD_ERR="$(rclone copyto "$TMP_T" "$WT" 2>&1 >/dev/null)" \
        || onx_die 3 "Drive yazma testi başarısız: ${GD_ERR:0:200}"
    rclone deletefile "$WT" >/dev/null 2>&1 || true

    LAT=$(_elapsed_ms)
    onx_json_out reachable true writeable true latency_ms "$LAT"
    ;;

*)
    onx_die 1 "Bilinmeyen tip: ${TYPE}"
    ;;
esac
