#!/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: only allow paths under /var/backups/onox or /mnt/backup
    [[ "$PATH_VAL" =~ ^(/var/backups/onox|/mnt/backup) ]] || \
        onx_die 1 "Güvensiz path: ${PATH_VAL}"

    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 -u "${USER},${PASS}" "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"

    RESTIC_PASSWORD="$PASS" restic -r "$REPO" snapshots >/dev/null 2>&1 \
        || onx_die 3 "Restic repo erişimi başarısız: ${REPO}"

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

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