#!/bin/sh

set -u

protocol_version=2

if [ "${1-}" = "--protocol-version" ]; then
    printf '%s\n' "$protocol_version"
    exit 0
fi

exit_useradd_failed=10
exit_password_failed_rolled_back=11
exit_password_failed_rollback_failed=12
exit_useradd_failed_account_present=13
exit_invalid_input=64

login=''
for arg in "$@"; do
    login="$arg"
done

if [ -z "$login" ]; then
    echo 'Missing login name' >&2
    exit "$exit_invalid_input"
fi

login_preexisted=0
if /usr/bin/getent passwd "$login" >/dev/null 2>&1; then
    login_preexisted=1
fi

IFS= read -r password
read_status=$?
if [ "$read_status" -ne 0 ]; then
    echo 'Missing password input' >&2
    exit "$exit_invalid_input"
fi

useradd_output=$(/usr/sbin/useradd "$@" 2>&1)
useradd_status=$?
if [ "$useradd_status" -ne 0 ]; then
    if [ "$login_preexisted" -eq 0 ] && /usr/bin/getent passwd "$login" >/dev/null 2>&1; then
        if [ -n "$useradd_output" ]; then
            printf '%s\n' "$useradd_output" >&2
        fi
        exit "$exit_useradd_failed_account_present"
    fi

    if [ -n "$useradd_output" ]; then
        printf '%s\n' "$useradd_output" >&2
    fi
    exit "$exit_useradd_failed"
fi

chpasswd_output=$(printf '%s:%s\n' "$login" "$password" | /usr/sbin/chpasswd 2>&1)
chpasswd_status=$?
if [ "$chpasswd_status" -eq 0 ]; then
    exit 0
fi

rollback_output=$(/usr/sbin/userdel "$login" 2>&1)
rollback_status=$?

if /usr/bin/getent passwd "$login" >/dev/null 2>&1; then
    if [ -n "$chpasswd_output" ]; then
        printf '%s\n' "$chpasswd_output" >&2
    fi
    if [ -n "$rollback_output" ]; then
        printf 'Rollback failed: %s\n' "$rollback_output" >&2
    fi
    exit "$exit_password_failed_rollback_failed"
fi

if [ -n "$chpasswd_output" ]; then
    printf '%s\n' "$chpasswd_output" >&2
fi
if [ "$rollback_status" -ne 0 ] && [ -n "$rollback_output" ]; then
    printf 'Account entry removed with warnings: %s\n' "$rollback_output" >&2
fi
exit "$exit_password_failed_rolled_back"
