#!/usr/bin/env bash
set -Eeuo pipefail

STATE_DIR="/var/lib/celita-user-manager"
RESET_DIR="/etc/celita-reset-users"

die() {
    printf 'ERRO: %s\n' "$*" >&2
    exit 1
}

[[ ${EUID} -eq 0 ]] || die "esta operação requer privilégios administrativos"
[[ $# -ge 1 ]] || die "operação não informada"

validate_user() {
    local username="$1" uid
    [[ "$username" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] || die "nome de usuário inválido"
    if getent passwd "$username" >/dev/null; then
        uid="$(id -u "$username")"
        [[ "$uid" -ge 1000 && "$uid" -lt 60000 ]] || die "conta protegida pelo sistema"
    fi
}

read_password() {
    PASSWORD=""
    IFS= read -r PASSWORD || true
    [[ "$PASSWORD" != *$'\n'* && "$PASSWORD" != *:* ]] || die "senha inválida"
}

set_password() {
    local username="$1" mode="$2"
    case "$mode" in
        keep) ;;
        none) passwd -d "$username" >/dev/null ;;
        set)
            [[ -n "$PASSWORD" ]] || die "a senha não pode ficar vazia"
            printf '%s:%s\n' "$username" "$PASSWORD" | chpasswd
            ;;
        *) die "modo de senha inválido" ;;
    esac
}

set_reset() {
    local username="$1" enabled="$2" home archive temporary
    home="$(getent passwd "$username" | cut -d: -f6)"
    [[ "$home" == /home/* && "$home" != /home/ ]] || die "diretório pessoal inseguro"
    archive="$STATE_DIR/baselines/$username/home.tar"
    if [[ "$enabled" == "yes" ]]; then
        mkdir -p "$STATE_DIR/baselines/$username" "$RESET_DIR"
        if [[ ! -f "$archive" ]]; then
            temporary="$archive.tmp"
            tar --acls --xattrs -C "$home" -cpf "$temporary" .
            mv -f "$temporary" "$archive"
        fi
        touch "$RESET_DIR/$username"
        chmod 0755 "$RESET_DIR"
        chmod 0644 "$RESET_DIR/$username"
    elif [[ "$enabled" == "no" ]]; then
        rm -f -- "$RESET_DIR/$username"
        rm -rf -- "$STATE_DIR/baselines/$username"
    else
        die "opção de reset inválida"
    fi
}

operation="$1"
case "$operation" in
    create)
        [[ $# -eq 5 ]] || die "argumentos inválidos"
        username="$2"
        full_name="$3"
        password_mode="$4"
        reset_enabled="$5"
        validate_user "$username"
        getent passwd "$username" >/dev/null && die "este usuário já existe"
        [[ "$full_name" != *:* && "$full_name" != *$'\n'* ]] || die "nome completo inválido"
        read_password
        useradd --create-home --shell /bin/bash --comment "$full_name" "$username"
        trap 'userdel --remove "$username" >/dev/null 2>&1 || true' ERR
        set_password "$username" "$password_mode"
        for group in audio video plugdev netdev; do
            getent group "$group" >/dev/null && usermod -aG "$group" "$username" || true
        done
        set_reset "$username" "$reset_enabled"
        trap - ERR
        ;;
    configure)
        [[ $# -eq 4 ]] || die "argumentos inválidos"
        username="$2"
        password_mode="$3"
        reset_enabled="$4"
        validate_user "$username"
        getent passwd "$username" >/dev/null || die "usuário não encontrado"
        read_password
        set_password "$username" "$password_mode"
        set_reset "$username" "$reset_enabled"
        ;;
    *) die "operação desconhecida" ;;
esac

exit 0
