#!/bin/bash

# **************************************************************************
# *                                                                        *
# *  Pointtools v.0.3 by Alexey Khromov AKA zxalexis AKA 2:5030/723        *
# *                                                                        *
# **************************************************************************
# *                                                                        *
# * pointsort - sort Links, Passwords and Userlist files for               *
# *     in ascending order, with check of consistency                      *
# *                                                                        *
# **************************************************************************

NMSBASE=""
FIDOBASE=""

if [ -f /etc/fidonms ]; then
    source /etc/fidonms
fi
if [ -z "$NMSBASE" ]; then
    #Try to guess
    NMSBASE=/opt/fidonms
fi
if [ -z "$FIDOBASE" ]; then
    FIDOBASE=/var/spool/ftn
fi

# Read parameters
while [ -n "$1" ]
do
        case "$1" in
                -f)     cfgfile="$2"
                        shift;;
                *)      cmdusage="1";;
        esac
        shift
done

if [[ "${cmdusage}" = "1" ]]; then
        echo -ne "Usage: \n\
pointsort {-f <cfgfile>}\n"
        exit -2
fi

pwdsource=${BASH_SOURCE[0]}
while [ -L "$pwdsource" ]; do
        pwddir=$( cd -P "$( dirname "$pwdsource" )" > /dev/null 2>&1 && pwd )
        pwdsource=$( readlink "$pwdsource" )
        [[ $pwdsource != /* ]] && pwdsource=$pwddir/$pwdsource
done
pwddir=$( cd -P "$( dirname "$pwdsource" )" > /dev/null 2>&1 && pwd )

if [[ -z ${cfgfile} ]]; then
        if [[ -f "${NMSBASE}/etc/pointcfg" ]]; then
                cfgfile="${NMSBASE}/etc/pointcfg"
        elif [[ -f "/etc/pointcfg" ]]; then
                cfgfile="/etc/pointcfg"
        elif [[ -f "$pwddir/etc/pointcfg" ]]; then
                cfgfile="$pwddir/etc/pointcfg"
        else
                echo "Config file not found. Please specify one"
                exit -2
        fi
fi

source ${cfgfile}


if [[ -f ${FIDOCONFIG} ]];
then
    AKA=$(grep -ie ^Address ${FIDOCONFIG} | head -n1 | awk -F'[ @]' '{ print $2 }')
else
    echo "No FIDOCONFIG var found..."
    break;
fi

errorlvl=0
declare -a upntarri=()
declare -A upntarrs=()
declare -a ppntarri=()
declare -A ppntarrs=()
declare -a lpntarri=()
declare -A lpntarrs=()
declare -A lpntarre=()

if [[ -f ${USERLIST} ]]; then
	lnum=0
	while read -r line; do
		lnum=$(( ${lnum} + 1 ))
		if [[ "$(echo -ne ${line}| awk -F',' '{ print $1 }')" =~ ^[Pp][Oo][Ii][Nn][Tt]$ ]]; then
			upnum=$(echo -ne ${line}| awk -F',' '{print $2}')
			upntarri+=(${upnum})
			upntarrs+=([${upnum}]=${lnum})
			# echo "Added upntarri ${upnum}"
		fi
	done < ${USERLIST}
else
	errorlvl=0
fi


if [[ -f ${BINKD_PASSWD} ]]; then
	lnum=0
	while read -r line; do
		lnum=$(( ${lnum} + 1 ))
		tmpaka="$(echo -ne ${line}| awk '{ print $1 }'| awk -F'.' '{ --NF; print }'| sed -e 's/ /./')"

		if [[ ${tmpaka} == ${AKA} ]]; then
			ppnum=$(echo -ne ${line}| awk '{ print $1 }'| awk -F'.' '{ print $NF }')
			ppntarri+=(${ppnum})
			ppntarrs+=([${ppnum}]=${lnum})
			# echo "Added ppntarri ${ppnum}"
		fi
		# Adding after to store previous lines
	done < ${BINKD_PASSWD}
else
	errorlvl=2
fi


if [[ -f ${HPT_POINTS} ]]; then
	lnum=0
	loclink=0
	while read -r line; do
		lnum=$(( ${lnum} + 1 ))
		if [[ "$(echo -ne ${line}| awk '{ print $1 }')" =~ ^[Ll][Ii][Nn][Kk]$ ]]; then
			
			# echo "Link begins at ${lnum}"
			if [ ${loclink} != 0 ]; then
				lpntarre+=([${lpnum}]=$(( $lnum - 1 )))
			fi	
			loclink=${lnum}
		fi
		if [[ "$(echo -ne ${line}| awk '{print $1 }')" =~ ^[Aa][Kk][Aa]$ ]]; then

			lpnum=$(echo -ne ${line}| awk '{print $2}'| awk -F'.' '{ print $NF }')
			lpntarri+=(${lpnum})
			lpntarrs+=([${lpnum}]=${loclink})
		fi
	done < ${HPT_POINTS}
	# Add last line to last pntnum
	lpntarre+=([${lpnum}]=${lnum})

	# echo "Lpntarri array is ${lpntarri[@]}"
	# echo "strings array is ${lpntarrs[@]}"
	# echo "ends array is ${lpntarre[@]}"
else
	# echo "No LINKS file found"
	errorlvl=2
fi

# Now we have indexes from all 3 files (userlist is optional, but preferrable
# We can a) compare them for consistency, b) find spare one c) throw out 
# indices for insertion
declare -a lsortedlst=()
declare -a usortedlst=()
declare -a psortedlst=()
readarray -t lsortedlst < <(printf '%s\n' "${lpntarri[@]}"| sort -g)
readarray -t psortedlst < <(printf '%s\n' "${ppntarri[@]}"| sort -g)
if [ -f "${USERLIST}" ]; then
	readarray -t usortedlst < <(printf '%s\n' "${upntarri[@]}"| sort -g)
	if [[ ${usortedlst[@]} != ${upntarri[@]} ]] && [[ ${errorlvl} = 0 ]]; then
		errorlvl=1
	elif [[ ${usortedlst[@]} != ${psortedlst[@]} ]] || [[ ${usortedlst[@]} != ${lsortedlst[@]} ]]; then
		errorlvl=2
	fi

fi
if [[ ${lsortedlst[@]} = ${psortedlst[@]} ]]; then
    	if [[ ${lsortedlst[@]} != ${lpntarri[@]} ]] || [[ ${psortedlst[@]} != ${ppntarri[@]} ]] ; then
		errorlvl=1
		# echo "LS: ${lsortedlst[@]}"
		# echo "LPNT: ${lpntarri[@]}"
		# echo "PS: ${psortedlst[@]}"
		# echo "PPNT: ${ppntarri[@]}"
	fi
else
	errorlvl=2
fi

if [[ ${errorlvl} = 1 ]]; then
	echo "Userdb files are not sorted - trying to sort..."

	# Writing USERLIST if exists
	if [[ -f ${USERLIST} ]]; then
		echo -en "${UDB_HEADER}" > ${USERLIST}.new
		for ipoint in ${usortedlst[@]}; do
			echo -ne "uline ${ipoint} "
			cat ${USERLIST}| sed -ne """${upntarrs[$ipoint]} p""" >> ${USERLIST}.new
		done
		echo -ne "\n"
	fi


	# Writing PASSWORDS:
	#
	echo -en "${PWDS_HEADER}" > ${BINKD_PASSWD}.new
	for ipoint in ${psortedlst[@]}; do
		echo -en "pline ${ipoint} "
		cat ${BINKD_PASSWD}| sed -ne """${ppntarrs[$ipoint]} p""" >> ${BINKD_PASSWD}.new
	done
	echo -en "\n"

	# Writing LINKS:
	#
	echo -en "${LINKS_HEADER}" > ${HPT_POINTS}.new
	for ipoint in ${lsortedlst[@]}; do
		echo -ne "lline ${ipoint} "
		cat ${HPT_POINTS}| sed -ne """${lpntarrs[$ipoint]},${lpntarre[$ipoint]}p""" >> ${HPT_POINTS}.new
	done
	echo -ne "\n"

	# Renaming files which sorted
	if [[ -f ${USERLIST} ]]; then
		mv -f ${USERLIST} ${USERLIST}.old
		mv -f ${USERLIST}.new ${USERLIST}
	fi

	mv -f ${BINKD_PASSWD} ${BINKD_PASSWD}.old
	mv -f ${BINKD_PASSWD}.new ${BINKD_PASSWD}

	mv -f ${HPT_POINTS} ${HPT_POINTS}.old
	mv -f ${HPT_POINTS}.new ${HPT_POINTS}


fi
