#!/bin/bash

## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.

## Accessible variables are:
## - SERVICE_NAME        Name of current service
## - DOCKER_BASE_IMAGE   Base image from which this service might be built if any
## - SERVICE_DATASTORE           Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE         Location on host of the CONFIGSTORE of this service


. lib/common

set -e


##
## "${BIND_CONFIG_DIR}"/bind.keys
##

## https://www.isc.org/bind-keys/

config_hash=$(docker inspect "$DOCKER_BASE_IMAGE" --format '{{ .Id }}')
if ! [ -e "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}"/bind.keys ]; then
    mkdir -p "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}"
    ## From alpine install
    ln -sf ../../usr/share/dnssec-root/bind-dnssec-root.keys \
       "${SERVICE_CONFIGSTORE}${BIND_CONFIG_DIR}"/bind.keys
fi


##
## "${BIND_CONFIG_DIR}"/rndc.key
##


if [ -d "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then
    ## When deleting file and docker is still running, due to named
    ## stopping and docker force-restart, this file will be recreated
    ## as a directory To avoid issues, if we detect this condition,
    ## let's just remove the directory

    rmdir "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key
fi

if ! [ -e "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then
    mkdir -p "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/
    docker run --rm -v "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}:${BIND_CONFIG_DIR}" \
           "$DOCKER_BASE_IMAGE" rndc-confgen -b 256 -a
    if ! [ -e "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key ]; then
        err "RNDC key-file generation failed."
        exit 1
    fi
fi
config_hash=$(e "$config_hash" "$(cat "${SERVICE_DATASTORE}${BIND_CONFIG_DIR}"/rndc.key)")

init-config-add "
$SERVICE_NAME:
  volumes:
    - \"$SERVICE_DATASTORE${BIND_CONFIG_DIR}/rndc.key:${BIND_CONFIG_DIR}/rndc.key:ro\"
"


##
## "${BIND_CONFIG_DIR}"/named.conf and others
##



cd src
cfg_files=("${BIND_CONFIG_DIR#/}"/{zones.rfc1918,{db,named}.*})
for file in "${cfg_files[@]}"; do
    if ! diff "$file" "$SERVICE_CONFIGSTORE"/"$file" >/dev/null 2>&1; then
        cp -v "$file" "$SERVICE_CONFIGSTORE"/"$file" >&2 || exit 1
    else
        echo "File $file already up to date." >&2
    fi
done
config_hash=$(p0 "$config_hash" "$(cat "${cfg_files[@]}")" | md5_compat)
cd ..

##
## user requested zones
##

vars_cfg=$(options-get vars 2>/dev/null) || true
zones_cfg=$(options-get zones 2>/dev/null) || true

if [ -n "$zones_cfg" ]; then
    ## will update config_hash
    bind:cfg:generate "$zones_cfg" "$vars_cfg"
fi


uid=$(docker_get_uid "$SERVICE_NAME" "named")

dirs=(/{etc,var/{log,cache}}/bind )
host_dirs=()
for dir in "${dirs[@]}"; do
    host_dirs+=("$SERVICE_DATASTORE$dir")
done
host_dirs+=("$SERVICE_CONFIGSTORE"/etc/bind)

mkdir -p "${host_dirs[@]}"
find "${host_dirs[@]}" \! -user "$uid" -or -type l -print0 | while read-0 f; do
    chown -v "$uid" "$f" || exit 1
done


##
## Final
##

init-config-add "
$MASTER_BASE_SERVICE_NAME:
  labels:
    - compose.config_hash=$config_hash
"