#!/bin/bash

# LibrePortal-managed SSH key store for backup locations. Each location's
# private key lives at configs/backup/locations/<idx>/ssh.key. Public key
# is derived on the fly via ssh-keygen -y, so we never persist it
# separately. The CFG_BACKUP_LOC_<idx>_SSH_AUTH selector (key|password)
# is the only ssh-related value in the location.config file.

# Refresh locations.json so the editor reflects new key state (public key /
# "key set" status) right after a mutation. No-op if the generator isn't loaded.
backupSshKeyRefreshUi()
{
    declare -f webuiGenerateBackupLocations >/dev/null 2>&1 && webuiGenerateBackupLocations >/dev/null 2>&1
    return 0
}

backupSshKeyFile()
{
    local idx="$1"
    backupLocationSshKey "$idx"
}

backupSshKeyExists()
{
    local idx="$1"
    [[ -f "$(backupSshKeyFile "$idx")" ]]
}

# Decode a base64-encoded private key and write it to the location's key
# file. The frontend base64-encodes pasted multi-line keys so we can ship
# them through the existing single-line task command pipeline.
backupSshKeySet()
{
    local idx="$1"
    local key_b64="$2"

    if [[ -z "$idx" || -z "$key_b64" ]]; then
        isError "backupSshKeySet requires <idx> <base64-key>"
        return 1
    fi

    backupLocationEnsureDir "$idx"
    local owner
    owner=$(backupLocationOwner)
    local key_file
    key_file=$(backupSshKeyFile "$idx")

    local decoded
    decoded=$(echo "$key_b64" | base64 -d 2>/dev/null)
    if [[ -z "$decoded" ]]; then
        isError "Failed to base64-decode the supplied key"
        return 1
    fi

    echo "$decoded" | runFileWrite "$key_file" >/dev/null
    runFileOp chown "$owner":"$owner" "$key_file"
    runFileOp chmod 0600 "$key_file"

    if ! sudo -u "$owner" ssh-keygen -y -f "$key_file" >/dev/null 2>&1; then
        isError "Key written but ssh-keygen can't read it — check the format (OpenSSH PEM: ed25519, rsa, ecdsa)"
        return 1
    fi

    isSuccessful "SSH key saved for location $idx"
    backupSshKeyRefreshUi
}

backupSshKeyGenerate()
{
    local idx="$1"
    if [[ -z "$idx" ]]; then
        isError "backupSshKeyGenerate requires <idx>"
        return 1
    fi

    backupLocationEnsureDir "$idx"
    local owner
    owner=$(backupLocationOwner)
    local key_file
    key_file=$(backupSshKeyFile "$idx")

    if [[ -f "$key_file" ]]; then
        runFileOp rm -f "$key_file" "${key_file}.pub"
    fi

    sudo -u "$owner" ssh-keygen -t ed25519 -f "$key_file" -N "" -C "libreportal-loc-${idx}" -q
    runFileOp chmod 0600 "$key_file"
    [[ -f "${key_file}.pub" ]] && runFileOp rm -f "${key_file}.pub"  # we re-derive when needed

    isSuccessful "Generated ed25519 keypair for location $idx"
    isNotice "Public key (paste into the remote host's ~/.ssh/authorized_keys):"
    backupSshKeyPublic "$idx"
    backupSshKeyRefreshUi
}

backupSshKeyPublic()
{
    local idx="$1"
    local key_file
    key_file=$(backupSshKeyFile "$idx")
    [[ -f "$key_file" ]] || return 1
    sudo -u "$(backupLocationOwner)" ssh-keygen -y -f "$key_file" 2>/dev/null
}

backupSshKeyDelete()
{
    local idx="$1"
    local key_file
    key_file=$(backupSshKeyFile "$idx")
    [[ -f "$key_file" ]] && runFileOp rm -f "$key_file" "${key_file}.pub"
    isSuccessful "SSH key removed for location $idx"
    backupSshKeyRefreshUi
}
