#!/bin/sh
# Write Asterisk the files nuxpbx owns, again.
#
# They are rendered once, at the first boot, which means a machine installed
# before a file existed never gets it. The security log fail2ban reads is one
# of those: the jail ships with the package, the log it watches is written by
# a logger.conf that only a fresh install ever received, so the bans on an
# upgraded machine watch an empty file for ever.
#
# Every file this writes says in its first line that nuxpbx wrote it and that
# changes are overwritten, so writing them again costs nothing. Asterisk's own
# files, the ones we only ever read, are not touched.
set -eu

env_file=${NUXPBX_ENV_FILE:-/etc/nuxpbx/nuxpbx.env}
[ -s "$env_file" ] || exit 0

# Line by line, the way systemd reads it: NUXPBX_DB is a connection string
# with spaces in it and no quotes around it, and `.` would turn
# "host=x port=y" into five assignments of which only the first is ours.
while IFS= read -r line; do
	case "$line" in '' | '#'*) continue ;; esac
	export "$line"
done <"$env_file"

nuxpbx config write "${NUXPBX_ASTERISK_CONFIG:-/etc/asterisk}"

# Asterisk reads a changed logger.conf only when told to. A reload rather
# than a restart: this runs on a machine that may be carrying a call.
#
# features.conf is the third of those, and the one nothing reloaded. It holds
# the two codes either party can press mid-call, and Asterisk keeps the
# applicationmap it read at start: the repair that moved *3 and *4 off Macro,
# which Asterisk 22 does not ship at all, was written to disk on upgrade after
# upgrade while the running Asterisk went on dialling the dead one. A box that
# was already on realtime gets no restart on an upgrade either, by design, so
# there was nothing else to pick it up.
#
# The dial plan is the fourth, and the one nothing read back either. It is the
# largest file this writes and the one every repair to the way a call is routed
# lands in, and Asterisk keeps the contexts it parsed at start: the *3 and *4
# repair went onto disk on upgrade after upgrade while the running switch went
# on dialling the Macro version. voicemail.conf is in the same position, and
# both are what a routing change already reloads over AMI when one is pressed
# in a browser. An upgrade is the one moment nobody presses anything.
if command -v asterisk >/dev/null 2>&1; then
	asterisk -rx 'logger reload' >/dev/null 2>&1 || true
	asterisk -rx 'module reload res_pjsip.so' >/dev/null 2>&1 || true
	# A load, not a reload, and it is allowed to fail. sorcery.conf mapped the
	# registration object under [res_pjsip], which is res_pjsip's own name and
	# not the name of the module that owns the type: the documentation lookup
	# failed and res_pjsip_outbound_registration declined to load on every
	# start since the first release. No trunk on any machine ever registered
	# with its provider, and nothing said so, because without the module
	# `pjsip show registrations` is not a command at all. A module that
	# declined stays declined over a reload, so the corrected file only
	# reaches a running switch if something loads it; where it is already
	# running this says "Unable to load" and changes nothing.
	asterisk -rx 'module load res_pjsip_outbound_registration.so' >/dev/null 2>&1 || true
	asterisk -rx 'module reload features' >/dev/null 2>&1 || true
	asterisk -rx 'dialplan reload' >/dev/null 2>&1 || true
	asterisk -rx 'module reload app_voicemail.so' >/dev/null 2>&1 || true
	# And rtp.conf, which is the one file here whose whole purpose is that
	# Asterisk and the firewall agree on a range of ports. res_rtp_asterisk
	# reads it when it loads and keeps what it read, and none of the five
	# reloads above touches it: run on Asterisk 22.10.1 with the file
	# rewritten from the compiled in 5000 to 31000 down to 10000 to 20000,
	# `rtp show settings` still answered 5000 to 31000 after all five, and
	# 10000 to 20000 after this one. Nothing else in the product reads the
	# file back either, so on a machine installed before rtp.conf was
	# rendered the upgrade left nuxpbx-firewall opening the new range while
	# Asterisk went on picking ports outside it, and the table ends in a
	# drop: audio in one direction, or none, with nothing saying why.
	asterisk -rx 'module reload res_rtp_asterisk.so' >/dev/null 2>&1 || true
fi
