#!/bin/sh
# Bootstrap sysrepo db with all modules required by confd
#
# 1. Load all yang models with /cfg/factory-config
# 2. [ if /cfg/startup-config is missing :: copy {factory} -> /cfg/startup-config ]
# 3. Import /cfg/startup -> {startup} ]
# 4. Clear running-config :: import NULL -> {running}
# 5. Start sysrepo-plugind
# 6. Activate startup-config by :: copy {startup} -> {running}
#
# It's all really simple ... this script takes care of 1-4
#

# /etc/confdrc controls the behavior or most of the gen-scripts,
# customize in an overlay when using Infix as an br2-external.
RC=/etc/confdrc
if [ "$1" = "-f" ] && [ -f "$2" ]; then
    RC=$2
fi

if [ ! -f "$RC" ]; then
    logger -sik -p user.error -t bootstrap "Missing rc file $RC" 2>/dev/null \
        || echo "Missing rc file $RC"
    exit 99
fi

# shellcheck disable=SC1090
. "$RC"

FACTORY_GEN="$(dirname "$FACTORY_CFG")/$(basename "$FACTORY_CFG" .cfg).gen"
FAILURE_GEN="$(dirname "$FAILURE_CFG")/$(basename "$FAILURE_CFG" .cfg).gen"

# Generate device's factory-config at first boot or on override
if [ ! -f "$FACTORY_GEN" ] || [ "$FACTORY_OVERRIDE" = "true" ]; then
    mkdir -p "$FACTORY_D"

    # Save the original templates (from the original image) used to create factory-config
    for file in $(find "$FACTORY_DEFAULTS_D" -type f); do
	cp "$file" "$FACTORY_D"
    done

    # Create an overlay for /etc/hostname to change the default in an br2-external
    gen-hostname                                            >"$FACTORY_D/20-hostname.json"
    # shellcheck disable=SC2086
    gen-interfaces $GEN_IFACE_OPTS                          >"$FACTORY_D/20-interfaces.json"

    [ -s "$FACTORY_D/20-hostkey.json"   ] || gen-hostkeys   >"$FACTORY_D/20-hostkey.json"

    # Optional commands (from an overlay) to run for br2-externals
    [ -x "$(command -v gen-ifs-custom)" ] && gen-ifs-custom >"$FACTORY_D/20-interfaces.json"
    [ -x "$(command -v gen-cfg-custom)" ] && gen-cfg-custom >"$FACTORY_D/30-config.json"

    rm -f "$FACTORY_GEN"
    # shellcheck disable=SC2046
    jq -s 'reduce .[] as $item ({}; . * $item)'	\
       $(find "$FACTORY_D" -name '*.json' | sort) >"$FACTORY_GEN"
    chmod 444 "$FACTORY_GEN"

    # TODO: Look for statically defined factory-config, based on the
    #       system's product ID, or just custom site-specific factory.

    # If we haven't found a more specific, better match, settle for
    # factory-config.gen as the system's factory-config.
    [ -h "$FACTORY_CFG" ] || ln -sf "$(basename "$FACTORY_GEN")" "$FACTORY_CFG"
fi

# Generate device's failure-config at first boot
if [ ! -f "$FAILURE_GEN" ] || [ "$FAILURE_OVERRIDE" = "true" ]; then
    mkdir -p "$FAILURE_D"

    # Save the original templates (from the original image) used to create failure-config
    for file in $(find "$FAILURE_DEFAULTS_D" -type f); do
	cp "$file" "$FAILURE_D"
    done

    gen-hostname   "$FAIL_HOSTNAME"                         >"$FAILURE_D/20-hostname.json"
    gen-interfaces                                          >"$FAILURE_D/20-interfaces.json"

    [ -s "$FAILURE_D/20-hostkey.json"   ] || gen-hostkeys   >"$FAILURE_D/20-hostkey.json"

    # Optional failure/error config to generate (or override) for br2-externals
    [ -x "$(command -v gen-err-custom)" ] && gen-err-custom >"$FAILURE_D/30-error.json"

    rm -f "$FAILURE_GEN"
    # shellcheck disable=SC2046
    jq -s 'reduce .[] as $item ({}; . * $item)'	\
       $(find "$FAILURE_D" -name '*.json' | sort) >"$FAILURE_GEN"
    chmod 444 "$FAILURE_GEN"

    [ -h "$FAILURE_CFG" ] || ln -sf "$(basename "$FAILURE_GEN")" "$FAILURE_CFG"
fi

if [ -n "$TESTING" ]; then
	echo "Done."
	exit 0
fi

# Drop all pre-initialized data from netopeer2 install, then re-create
# with required netopeer2 models, sysrepo implicitly installs its own,
# and then we initialize it all with our factory defaults.
rm -rf /etc/sysrepo/* /dev/shm/sr_*
mkdir -p /etc/sysrepo/
cp "$FACTORY_CFG" "$INIT_DATA"
sysrepoctl -s $SEARCH							\
	   -i ietf-system@2014-08-06.yang      -g wheel -p 0660		\
           	-e authentication					\
		-e local-users						\
		-e ntp							\
		-e ntp-udp-port						\
		-e timezone-name					\
	   -i iana-timezones@2013-11-19.yang   -g wheel -p 0660		\
	   -i nc-notifications@2008-07-14.yang -g wheel -p 0660		\
	   -i notifications@2008-07-14.yang    -g wheel -p 0660		\
	   -i ietf-keystore@2019-07-02.yang    -g wheel -p 0660		\
	   	-e keystore-supported					\
	   	-e local-definitions-supported				\
	   	-e key-generation					\
	   -i ietf-truststore@2019-07-02.yang	-g wheel -p 0660	\
		-e truststore-supported					\
		-e x509-certificates					\
	   -i ietf-tcp-common@2019-07-02.yang	-g wheel -p 0660	\
		-e keepalives-supported					\
	   -i ietf-ssh-server@2019-07-02.yang	-g wheel -p 0660	\
		-e local-client-auth-supported				\
	   -i ietf-tls-server@2019-07-02.yang	-g wheel -p 0660	\
		-e local-client-auth-supported				\
 	   -i ietf-netconf-server@2019-07-02.yang -g wheel -p 0660	\
	   	-e ssh-listen						\
		-e tls-listen						\
		-e ssh-call-home					\
		-e tls-call-home					\
	   -i ietf-interfaces@2018-02-20.yang   -g wheel -p 0660	\
		-e if-mib						\
	   -i ietf-ip@2018-02-22.yang		-g wheel -p 0660	\
		-e ipv6-privacy-autoconf				\
	   -i ietf-network-instance@2019-01-21.yang -g wheel -p 0660	\
	   -i ietf-netconf-monitoring@2010-10-04.yang -g wheel -p 0660	\
	   -i ietf-netconf-nmda@2019-01-07.yang -g wheel -p 0660	\
		-e origin						\
		-e with-defaults					\
	   -i ietf-subscribed-notifications@2019-09-09.yang		\
		-g wheel -p 0660 					\
		-e encode-xml						\
		-e replay						\
		-e subtree						\
		-e xpath						\
	   -i ietf-yang-push@2019-09-09.yang    -g wheel -p 0660	\
		-e on-change						\
	   -i iana-if-type@2023-01-26.yang	-g wheel -p 0660	\
	   -i ietf-if-extensions@2023-01-26.yang -g wheel -p 0660	\
		-e sub-interfaces					\
	   -i ieee802-dot1q-types@2022-10-29.yang -g wheel -p 0660	\
	   -i ietf-if-vlan-encapsulation@2023-01-26.yang		\
		-g wheel -p 0660 					\
	   -i infix-ip@2023-09-14.yang		-g wheel -p 0660	\
	   -i infix-if-type@2023-08-21.yang	-g wheel -p 0660	\
	   -i infix-interfaces@2023-09-19.yang	-g wheel -p 0660	\
		-e vlan-filtering					\
	   -i ieee802-dot1ab-lldp@2022-03-15.yang -g wheel -p 0660	\
	   -i infix-lldp@2023-08-23.yang	-g wheel -p 0660	\
	   -i infix-dhcp-client@2023-05-22.yang -g wheel -p 0660	\
	   -i infix-shell-type@2023-08-21.yang	-g wheel -p 0660	\
	   -i infix-system@2023-08-15.yang	-g wheel -p 0660	\
	   -i infix-services@2023-10-16.yang	-g wheel -p 0660	\
	   -I "${INIT_DATA}"
rc=$?

# Unlike `sysrepoctl -i` the `-c` command requires separate invocations.
# NOTE: we ignore any errors from these at bootstrap since sysrepo may
#       already enable some of these feature, resulting in error here.
# Enable features required by netopeer2
sysrepoctl -c ietf-netconf			-g wheel -p 0660	\
		-e writable-running					\
		-e candidate						\
		-e rollback-on-error					\
		-e validate						\
		-e startup						\
		-e url							\
		-e xpath						\
		-e confirmed-commit
# Allow wheel group users (admin) to modify NACM
sysrepoctl -c ietf-netconf-acm -g wheel -p 0660

# On first boot, install factory-config as startup-config.  Due to a
# limitation in sysrepo we cannot initialize ietf-netconf-acm, so we
# cheat, see sysrepo#3079
if [ ! -f "$STARTUP_CFG" ]; then
    sysrepocfg -f json -X"$STARTUP_CFG"
fi

# Clear running-config so we can load startup in the next step
echo "{}" > "$INIT_DATA"
sysrepocfg -f json -I"$INIT_DATA" -d running

exit $rc
