#!/bin/bash
#
# Copyright (c) Authors: https://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.

SIZE=50M
USE_RSYNC=true
ENABLED=false

[ -f /etc/default/orangepi-ramlog ] && . /etc/default/orangepi-ramlog

[ "$ENABLED" != true ] && exit 0

# Never touch anything below here. Only edit /etc/default/orangepi-ramlog

HDD_LOG=/var/log.hdd/
RAM_LOG=/var/log/
LOG2RAM_LOG="${HDD_LOG}orangepi-ramlog.log"
LOG_OUTPUT="tee -a $LOG2RAM_LOG"

isSafe () {
	[ -d $HDD_LOG ] || (echo "ERROR: $HDD_LOG doesn't exist! Can't sync." >&2 ; exit 1)
	NoCache=$(command -v nocache 2>/dev/null)
}

RecreateLogs (){
	# in case of crash those services don't start if there are no dirs & logs
	check_if_installed apache2 && [ ! -d /var/log/apache2 ] && mkdir -p /var/log/apache2
	check_if_installed cron-apt && [ ! -d /var/log/cron-apt ] && \
		(mkdir -p /var/log/cron-apt ; touch /var/log/cron-apt/log)
	check_if_installed proftpd-basic && [ ! -d /var/log/proftpd ] && \
		(mkdir -p /var/log/proftpd ; touch /var/log/proftpd/controls.log)
	check_if_installed nginx && [ ! -d /var/log/nginx ] && \
		(mkdir -p /var/log/nginx ; touch /var/log/nginx/access.log ; touch /var/log/nginx/error.log)
	check_if_installed lighttpd && [ ! -d /var/log/lighttpd ] && \
		(mkdir -p /var/log/lighttpd ; touch /var/log/lighttpd/access.log ; touch /var/log/lighttpd/error.log)
	check_if_installed samba && [ ! -d /var/log/samba ] && mkdir -p /var/log/samba
	check_if_installed unattended-upgrades && [ ! -d /var/log/unattended-upgrades ] && mkdir -p /var/log/unattended-upgrades
	return 0
}

syncToDisk () {
	isSafe

	echo -e "\n\n$(date): Syncing logs to storage\n" | $LOG_OUTPUT

	if [ "$USE_RSYNC" = true ]; then
		${NoCache} rsync -aXWv \
			--exclude "lost+found" --exclude orangepi-ramlog.log \
			--links \
			${XTRA_RSYNC_TO[@]+"${XTRA_RSYNC_TO[@]}"} \
			$RAM_LOG $HDD_LOG 2>&1 | $LOG_OUTPUT
	else
		${NoCache} cp -rfup $RAM_LOG -T $HDD_LOG 2>&1 | $LOG_OUTPUT
	fi

	sync /
}

syncFromDisk () {
	isSafe

	echo -e "\n\n$(date): Loading logs from storage\n" | $LOG_OUTPUT

	if [ "$USE_RSYNC" = true ]; then
		${NoCache} rsync -aXWv --delete \
			--exclude "lost+found" --exclude orangepi-ramlog.log \
			--exclude *.gz --exclude *.xz --exclude='*.[0-9]' \
			--links \
			${XTRA_RSYNC_FROM[@]+"${XTRA_RSYNC_FROM[@]}"} \
			$HDD_LOG $RAM_LOG 2>&1 | $LOG_OUTPUT
	else
		${NoCache} find $HDD_LOG* -maxdepth 1 -type f -not \( -name '*.[0-9]' -or -name '*.xz*' -or -name '*.gz' \) | xargs cp -ut $RAM_LOG
	fi

	sync /
}

check_if_installed () {
	local DPKG_Status="$(dpkg -s "$1" 2>/dev/null | awk -F": " '/^Status/ {print $2}')"
	if [[ "X${DPKG_Status}" = "X" || "${DPKG_Status}" = *deinstall* ]]; then
		return 1
	else
		return 0
	fi
}

case "$1" in
	start)
		[ -d $HDD_LOG ] || mkdir -p $HDD_LOG
		mount --bind $RAM_LOG $HDD_LOG
		mount --make-private $HDD_LOG
		
		# Check whether zram device is available or we need to use tmpfs
		LOG_TYPE="tmpfs"
		for rd in /dev/zram*; do
			if [[ "$(e2label $rd)" == "log2ram" ]]; then
				LOG_TYPE="zram"
				break
			fi
		done
		case $LOG_TYPE in
			zram)
				echo -e "Mounting $rd as $RAM_LOG \c" | $LOG_OUTPUT
				mount -o discard $rd $RAM_LOG 2>&1 | $LOG_OUTPUT
				;;
			tmpfs)
				echo -e "Setting up $RAM_LOG as tmpfs \c" | $LOG_OUTPUT
				mount -t tmpfs -o nosuid,noexec,nodev,mode=0755,size=$SIZE orangepi-ramlog $RAM_LOG 2>&1 | $LOG_OUTPUT
				;;
		esac

		syncFromDisk
		RecreateLogs
		;;
	stop)
		syncToDisk
		umount -l $RAM_LOG
		umount -l $HDD_LOG
		;;
	write)
		syncToDisk
		;;
	postrotate)
		cd /var/log.hdd/
		find . -type f -print | grep -E -v "(\.gz|\.xz|\.[0-9]|orangepi-ramlog)" | while IFS= read -r  file
		do
	    		dest="/var/log/$file"
	    		cat $file > $dest	    
		done
		;;
	*)
		echo "Usage: ${0##*/} {start|stop|write}" >&2
		exit 1
		;;
esac
