#!/usr/bin/env bash
# =============================================================================
# onx-user-password — Reset Linux / FTP / WebDAV passwords
#
# Purpose:
#   Updates one or more credential stores for a hosting account depending on
#   the requested scope. Passwords must already be hashed by the caller where
#   expected (chpasswd accepts pre-hashed passwords in "$6$..." format, or
#   plain text when the caller has already applied server-side hashing).
#
# Input (stdin JSON):
#   {
#     "username": "onx_xxxx",
#     "password": "<cleartext or hashed>",   -- required
#     "scope":    "linux|ftp|webdisk|all"    -- default "all"
#   }
#
# Output (stdout JSON):
#   {"username":..., "updated":["linux","ftp","webdisk"]}
#
# Exit codes: 0=ok 1=invalid-input 2=preflight-fail 3=exec-fail 4=rolled-back 5=rollback-failed
#
# Sudoers entry needed:
#   apache ALL=(root) NOPASSWD: /usr/local/onoxsoft/bin/onx-user-password
#   Defaults!/usr/local/onoxsoft/bin/onx-user-password !requiretty
#   Defaults!/usr/local/onoxsoft/bin/onx-user-password log_output, log_input
#
# Deployed to: /usr/local/onoxsoft/bin/onx-user-password
# =============================================================================

set -euo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"

# ── Constants ─────────────────────────────────────────────────────────────────
WEBDISK_PASSWD_FILE="/etc/onox/webdisk.passwd"
VALID_SCOPES=("linux" "ftp" "webdisk" "all")

# ── Dependencies ──────────────────────────────────────────────────────────────
command -v jq       >/dev/null 2>&1 || { printf '{"error":"jq required"}\n' >&2; exit 2; }
command -v chpasswd >/dev/null 2>&1 || { printf '{"error":"chpasswd required"}\n' >&2; exit 2; }
require_root

# ── Read & parse stdin ────────────────────────────────────────────────────────
INPUT=$(cat)
onx_require_json "${INPUT}"

USERNAME=$(onx_json_get "${INPUT}" "username")
PASSWORD=$(onx_json_get "${INPUT}" "password")
SCOPE=$(onx_json_get    "${INPUT}" "scope" "all")

# ── Input validation ──────────────────────────────────────────────────────────
onx_validate_username "${USERNAME}"
[[ -z "${PASSWORD}" ]] && onx_die 1 "password is required"

SCOPE_VALID=false
for s in "${VALID_SCOPES[@]}"; do
    [[ "$s" == "${SCOPE}" ]] && SCOPE_VALID=true && break
done
[[ "${SCOPE_VALID}" == "true" ]] || onx_die 1 "invalid scope '${SCOPE}': must be linux|ftp|webdisk|all"

# ── Preflight ─────────────────────────────────────────────────────────────────
id "${USERNAME}" &>/dev/null || onx_die 2 "Linux user does not exist: ${USERNAME}"
mkdir -p "$(dirname "${WEBDISK_PASSWD_FILE}")"

# ── Apply passwords ───────────────────────────────────────────────────────────
UPDATED=()

# Linux password via chpasswd
if [[ "${SCOPE}" == "linux" || "${SCOPE}" == "all" ]]; then
    printf '%s:%s\n' "${USERNAME}" "${PASSWORD}" | chpasswd || \
        onx_die 3 "chpasswd failed for ${USERNAME}"
    onx_log "linux password updated: ${USERNAME}"
    UPDATED+=("linux")
fi

# FTP password via pure-pw
if [[ "${SCOPE}" == "ftp" || "${SCOPE}" == "all" ]]; then
    if command -v pure-pw >/dev/null 2>&1; then
        printf '%s\n%s\n' "${PASSWORD}" "${PASSWORD}" | \
            pure-pw passwd "${USERNAME}" -m 2>/dev/null || \
            onx_die 3 "pure-pw passwd failed for ${USERNAME}"
        onx_log "FTP password updated: ${USERNAME}"
        UPDATED+=("ftp")
    else
        onx_log "WARNING: pure-pw not installed, skipping FTP password"
    fi
fi

# WebDAV/WebDisk password via htpasswd
# v3.43 FIX: Apache vhost template per-user `${USER_HOME}/.htpasswds/webdisk` okuyor
# AMA bu script /etc/onox/webdisk.passwd global file yazıyordu → path mismatch,
# webdisk auth çalışmıyordu. Çözüm: HER İKİ DOSYAYA da yaz (Apache per-user okur,
# Nginx/OLS/Caddy ileride global'den okuyabilir).
if [[ "${SCOPE}" == "webdisk" || "${SCOPE}" == "all" ]]; then
    if command -v htpasswd >/dev/null 2>&1; then
        # 1) Per-user file (Apache vhost'ın okuduğu dosya)
        USER_HOME="/home/users/${USERNAME}"
        [[ -d "/home/${USERNAME}" ]] && USER_HOME="/home/${USERNAME}"  # legacy fallback
        PER_USER_HTPASSWD_DIR="${USER_HOME}/.htpasswds"
        PER_USER_HTPASSWD_FILE="${PER_USER_HTPASSWD_DIR}/webdisk"
        mkdir -p "${PER_USER_HTPASSWD_DIR}"
        chmod 0700 "${PER_USER_HTPASSWD_DIR}" 2>/dev/null || true
        chown "${USERNAME}:${USERNAME}" "${PER_USER_HTPASSWD_DIR}" 2>/dev/null || true

        PER_USER_FLAG="-b"
        [[ ! -f "${PER_USER_HTPASSWD_FILE}" ]] && PER_USER_FLAG="-bc"
        if htpasswd ${PER_USER_FLAG} "${PER_USER_HTPASSWD_FILE}" "${USERNAME}" "${PASSWORD}" 2>/dev/null; then
            chmod 0640 "${PER_USER_HTPASSWD_FILE}" 2>/dev/null || true
            chown "${USERNAME}:webserver" "${PER_USER_HTPASSWD_FILE}" 2>/dev/null || \
                chown "${USERNAME}:apache" "${PER_USER_HTPASSWD_FILE}" 2>/dev/null || true
            onx_log "webdisk per-user passwd updated: ${PER_USER_HTPASSWD_FILE}"
        else
            onx_log "WARNING: htpasswd per-user fail (continuing global)"
        fi

        # 2) Global file (legacy /etc/onox/webdisk.passwd — Nginx/OLS/Caddy ileride)
        HTPASSWD_FLAG="-b"
        if [[ ! -f "${WEBDISK_PASSWD_FILE}" ]]; then
            HTPASSWD_FLAG="-bc"
        fi
        if htpasswd ${HTPASSWD_FLAG} "${WEBDISK_PASSWD_FILE}" "${USERNAME}" "${PASSWORD}" 2>/dev/null; then
            chmod 0640 "${WEBDISK_PASSWD_FILE}" 2>/dev/null || true
            chown root:webserver "${WEBDISK_PASSWD_FILE}" 2>/dev/null || \
                chown root:apache "${WEBDISK_PASSWD_FILE}" 2>/dev/null || true
            onx_log "webdisk global passwd updated: ${WEBDISK_PASSWD_FILE}"
        fi
        UPDATED+=("webdisk")
    else
        onx_log "WARNING: htpasswd not installed, skipping webdisk password"
    fi
fi

# ── Build updated array JSON ──────────────────────────────────────────────────
UPDATED_JSON=$(printf '%s\n' "${UPDATED[@]+"${UPDATED[@]}"}" | \
    jq -Rsc 'split("\n") | map(select(. != ""))')

# ── Output ────────────────────────────────────────────────────────────────────
printf '{"username":"%s","updated":%s}\n' "${USERNAME}" "${UPDATED_JSON}"
