#!/usr/bin/env bash
#######################################################
#                                                     #
#            Host, TG, and ID DB files Updater        #
#                     by W0CHP                        #
#                                                     #
#######################################################

echo "Starting WPSD Host, TG, and ID DB files update script..."

# Check if we are root
if [ "$(id -u)" != "0" ]; then
  echo "This script must be run as root" 1>&2
  exit 1
fi

source /usr/local/sbin/.wpsd-common-funcs

ProgVer="WPSD-Hostfile_Updater_v6.1"

OptIntoDiags_value=${OptIntoDiags_value:-true}

if [ "$OptIntoDiags_value" != 'true' ]; then
  echo "User has opted out of updates and diagnostics. Exiting..."
  exit 1
fi

# check age of task marker file if it exists, and if it's < N hours young, bail.
echo "Checking hostfile age..."
if [[ ${FORCE} -ne 1 ]]; then # please be thoughtful here. This env. var.
  # is called by a few places in the admin pages.
  if [ -f '/var/run/hostfiles-up' ] && [ "$(( $(date +"%s") - $(stat -c "%Y" "/var/run/hostfiles-up") ))" -lt "1" ];
  then
    echo "Hostfiles are less than 4 hours old. Not updating."
    echo "To force an update, run 'sudo FORCE=1 $(basename "$0")'"
    exit 0
  fi
fi

exec 200>/var/lock/wpsd-hostfiles.lock ||
exit 1 # only one exec per time
if ! flock -n 200 ;
then
  echo "Process already running"
  exit 1
fi

# connectivity check
echo "Performing connectivity check to WPSD Hostfile Update Server..."
conn_check
if $connection_established; then
  echo "WPSD Hostfile Update Server connection OK...downloading hostfiles."
else
  echo "WPSD Hostfile Update Server connection failed."
  exit 1
fi


base_dir="/usr/local/etc/tmp"

##checksum_file 变量定义
## [校验功能已屏蔽] checksum_file="/tmp/hostfile-checksums"

if [ ! -d $base_dir ]; then
  mkdir -p $base_dir
fi

##  删除旧校验清单
rm -rf $base_dir/hostfile-checksums

## 下载`hostfile-checksums` 校验清单
## [校验功能已屏蔽] echo "Downloading hostfile checksums..."
## [校验功能已屏蔽] curl --fail -L -o $checksum_file -s $hostFileURL/hostfile-checksums --user-agent "$ProgVer"

echo "Downloading WPSD hostfiles archive..."
curl --fail -L -o $base_dir/wpsd-hostfiles.tar.bz2 -s $hostFileURL/wpsd-hostfiles.tar.bz2 --user-agent "$ProgVer"
## [更换下载地址] curl --fail -L -o /usr/local/etc/tmp/wpsd-hostfiles.tar.bz2 -s http://bh5hwp.zj130.com/wpsd/update/wpsd-hostfiles.tar.bz2

##"Checking file integrities..." 提示
## [校验功能已屏蔽] echo "Checking file integrities..."
tar jxf $base_dir/wpsd-hostfiles.tar.bz2 -C $base_dir/

##整个 SHA-256 while 校验循环
## [校验功能已屏蔽] ===== SHA-256 校验循环开始（已屏蔽，不执行） =====
##while IFS=" " read -r expected_checksum filename;
##do
##  if [[ ! -f "$base_dir/$filename" ]];then
##    echo "Error: File $filename not found in $base_dir"
##    exit 1
##  fi
##  actual_checksum=$(sha256sum "$base_dir/$filename" | awk '{print $1}')
##  if [[ "$actual_checksum" != "$expected_checksum" ]];then
##    echo "Error: Checksum mismatch for $filename"
##    exit 1
##  fi
##done < "$checksum_file"
##echo "Hostfile checksums OK. Updating with new hostfiles..."
## [校验功能已屏蔽] ===== SHA-256 校验循环结束 =====

APRSHOSTS=$base_dir/APRSHosts.txt
APRSSERVERS=$base_dir/aprs_servers.json
DMRHOSTS=$base_dir/DMR_Hosts.txt
DPlusHOSTS=$base_dir/DPlus_Hosts.txt
XLXHOSTS=$base_dir/XLXHosts.txt
CCSHOSTS=$base_dir/CCS_Hosts.txt
DCSHOSTS=$base_dir/DCS_Hosts.txt
DExtraHOSTS=$base_dir/DExtra_Hosts.txt
YSFHOSTS=$base_dir/YSFHosts.txt
P25HOSTS=$base_dir/P25Hosts.txt
NXDNHOSTS=$base_dir/NXDNHosts.txt
DMRIDFILE=$base_dir/DMRIds.dat
RADIOIDDB_TMP=$base_dir/user.csv.tmp
RADIOIDDB=$base_dir/user.csv
STRIPPED=$base_dir/stripped.csv
BMTGNAMES=$base_dir/BM_TGs.json
GROUPSTXT=$base_dir/groups.txt

#解压后删除部分文件
echo "Delete file /usr/local/etc/tmp/ DMRIds.dat.bz2 NXDN.csv DMR_Hosts.txt APRSHosts.txt "
rm -rf /usr/local/etc/tmp/DMRIds.dat.bz2
rm -rf /usr/local/etc/tmp/user.csv.bz2
rm -rf /usr/local/etc/tmp/NXDN.csv
rm -rf /usr/local/etc/tmp/DMR_Hosts.txt
rm -rf /usr/local/etc/tmp/APRSHosts.txt

echo "Delete file /usr/local/etc/ user.csv NXDN.csv DMRIds.dat stripped.csv APRSHosts.txt DMR_Hosts.txt"
chattr -i /usr/local/etc/user.csv
chattr -e /usr/local/etc/user.csv
rm -rf /usr/local/etc/user.csv
chattr -i /usr/local/etc/NXDN.csv
chattr -e /usr/local/etc/NXDN.csv
rm -rf /usr/local/etc/NXDN.csv
chattr -i /usr/local/etc/DMRIds.dat
chattr -e /usr/local/etc/DMRIds.dat
rm -rf /usr/local/etc/DMRIds.dat
chattr -i /usr/local/etc/stripped.csv
chattr -e /usr/local/etc/stripped.csv
rm -rf /usr/local/etc/stripped.csv
chattr -i /usr/local/etc/APRSHosts.txt
chattr -e /usr/local/etc/APRSHosts.txt
rm -rf /usr/local/etc/APRSHosts.txt
chattr -i /usr/local/etc/DMR_Hosts.txt
chattr -e /usr/local/etc/DMR_Hosts.txt
rm -rf /usr/local/etc/DMR_Hosts.txt

#从新下载新的文件
echo "Processing APRSHosts (APRSHosts.txt)..."
curl --fail -L -o /usr/local/etc/tmp/APRSHosts.txt -s http://bh5hwp.zj130.com/8601/wpsd/update/APRSHosts.txt

echo "Processing DMR_Hosts (DMR_Hosts.txt)..."
curl --fail -L -o /usr/local/etc/tmp/DMR_Hosts.txt -s http://bh5hwp.zj130.com/8601/wpsd/update/DMR_Hosts.txt

echo "Processing Radio ID NXDN database (NXDN.csv)..."
curl --fail -L -o /usr/local/etc/tmp/NXDN.csv -s http://bh5hwp.zj130.com/8601/wpsd/update/NXDN.csv

echo "Processing Radio ID DMRIds.dat.bz2 database (DMRIds.dat.bz2)..."
curl --fail -L -o /usr/local/etc/tmp/DMRIds.dat.bz2 -s http://bh5hwp.zj130.com/8601/wpsd/update/DMRIds.dat.bz2

echo "Processing Radio ID user.csv.bz2 database (user.csv.bz2)..."
curl --fail -L -o /usr/local/etc/tmp/user.csv.bz2 -s http://bh5hwp.zj130.com/8601/wpsd/update/user.csv.bz2

#1. APRS
APRSOVR=/root/APRSHosts.txt
if [[ -f $APRSOVR && $(grep --text -v '#' $APRSOVR) != '' ]]; then
  echo "APRSHosts overrides found. Applying..."
  # If there is a APRS Hosts override file, merge its contents
  grep --text -v '#' $APRSOVR | tr -d '\r' | grep --text -vFxf $APRSHOSTS >> $APRSHOSTS
  # Converting APRSHosts into aprs_servers.json and merge its contents
  grep --text -v '#' $APRSOVR | tr -d '\r' | jq -R -n '[inputs | select(startswith("#") | not) | split(";") | select(length >= 2) | {id: (if length >= 3 then .[2] else .[1] end), fqdn: (.[0] | split(":")[0])}]' > $APRSSERVERS.txt_gen
  jq -s 'flatten | unique' $APRSSERVERS $APRSSERVERS.txt_gen > $APRSSERVERS.tmp && mv $APRSSERVERS.tmp $APRSSERVERS
  rm -f $APRSSERVERS.txt_gen
fi

#2. DMR
DMROVR=/root/DMR_Hosts.txt
if [[ -f $DMROVR && $(grep --text -v '#' $DMROVR) != '' ]]; then
  echo "DMR_Hosts overrides found. Applying..."
  # If there is a DMR override file,, merge its contents
  grep --text -v '#' $DMROVR | tr -d '\r' | grep --text -vFxf $DMRHOSTS >> $DMRHOSTS
fi

DPLUSOVR=/root/DPlus_Hosts.txt
if [[ -f $DPLUSOVR && $(grep --text -v '#' $DPLUSOVR) != '' ]]; then
  echo "D-Plus overrides found. Applying..."
  # If there is a D-Plus override file, merge its contents
  grep --text -v '#' $DPLUSOVR | tr -d '\r' | grep --text -vFxf $DPlusHOSTS >> $DPlusHOSTS
fi

XLXOVR=/root/XLXHosts.txt
if [ -f $XLXOVR ]; then
  # If there is a XLX override file, merge its contents
  while IFS= read -r line; do
    if [[ $line != \#* && $line = *";"* ]]; then
      echo "XLXHosts overrides found. Applying..."
      xlxid=$(echo "$line" | awk -F ';' '{print $1}')
      xlxip=$(echo "$line" | awk -F ';' '{print $2}')
      xlxroom=$(echo "$line" | awk -F ';' '{print $3}')
      xlxNewLine="$xlxid;$xlxip;$xlxroom"

      if grep -q "^$xlxid;" $XLXHOSTS; then
        sed -i "s/^$xlxid;.*/$xlxNewLine/" $XLXHOSTS
      else
        echo $xlxNewLine >> $XLXHOSTS
      fi
    fi
  done < $XLXOVR
  { grep '^#' "$XLXHOSTS"; grep -v '^#' "$XLXHOSTS" | sort -t ';' -k1,1; } > "${XLXHOSTS}.tmp" && mv "${XLXHOSTS}.tmp" "$XLXHOSTS"
fi

# Fix DMRGateway issues with parens
if [ -f "/etc/dmrgateway" ]; then
  sed -i '/Name=.*(/d' /etc/dmrgateway
  sed -i '/Name=.*)/d' /etc/dmrgateway
fi

#3. DSTAR
CCSOVR=/root/CCS_Hosts.txt
if [[ -f $CCSOVR && $(grep --text -v '#' $CCSOVR) != '' ]]; then
  echo "CCS_Hosts overrides found. Applying..."
  # If there is a CCS override file,, merge its contents
  grep --text -v '#' $CCSOVR | tr -d '\r' | grep --text -vFxf $CCSHOSTS >> $CCSHOSTS
fi

DCSOVR=/root/DCS_Hosts.txt
if [[ -f $DCSOVR && $(grep --text -v '#' $DCSOVR) != '' ]]; then
  echo "DCS_Hosts overrides found. Applying..."
  # If there is a DCS override file,, merge its contents
  grep --text -v '#' $DCSOVR | tr -d '\r' | grep --text -vFxf $DCSHOSTS >> $DCSHOSTS
fi

DEXTRAOVR=/root/DExtra_Hosts.txt
if [[ -f $DEXTRAOVR && $(grep --text -v '#' $DEXTRAOVR) != '' ]]; then
  echo "D-Extra overrides found. Applying..."
  # If there is a D-Extra override file, merge its contents
  grep --text -v '#' $DEXTRAOVR | tr -d '\r' | grep --text -vFxf $DExtraHOSTS >> $DExtraHOSTS
fi

# 4. YSF
YSFOVR=/root/YSFHosts.txt
if [[ -f $YSFOVR && $(grep --text -v '#' $YSFOVR) != '' ]]; then
  echo "YSFHosts overrides found. Applying..."
  # If there is a YSF override file,, merge its contents
  grep --text -v '#' $YSFOVR | tr -d '\r' | grep --text -vFxf $YSFHOSTS >> $YSFHOSTS
fi

# 5. P25
P25OVR=/root/P25Hosts.txt
if [[ -f $P25OVR && $(grep --text -v '#' $P25OVR) != '' ]]; then
  echo "P25Hosts overrides found. Applying..."
  # If there is a P25 override file, merge its contents
  grep --text -v '#' $P25OVR | tr -d '\r' | grep --text -vFxf $P25HOSTS >> $P25HOSTS
fi

# 6. NXDN
NXDNOVR=/root/NXDNHosts.txt
if [[ -f $NXDNOVR && $(grep --text -v '#' $NXDNOVR) != '' ]]; then
  echo "NXDNHosts overrides found. Applying..."
  # If there is a NXDN override file, merge its contents
  grep --text -v '#' $NXDNOVR | tr -d '\r' | grep --text -vFxf $NXDNHOSTS >> $NXDNHOSTS
fi

echo "Processing DMR ID database..."
# Get DMR IDs
mv ${DMRIDFILE}.bz2 /tmp/
bunzip2 -f /tmp/DMRIds.dat.bz2
# filter out IDs less than 7 digits (causing collisions with TGs of < 7 digits in "Target" column"
cat /tmp/DMRIds.dat  2>/dev/null | grep -v '^#' | awk '($1 > 999999) && ($1 < 10000000) { print $0 }' | sort -un -k1n -o ${DMRIDFILE}
rm -f /tmp/DMRIds.dat

echo "Updating BrandMeister Talkgroup list..."
# BM TG List for live caller and (legacy) nextion screens:
cp ${BMTGNAMES} ${GROUPSTXT}

echo "Processing Radio ID DMR database (user.csv)..."
# Nextion and LiveCaller DMR ID DB's
bunzip2 -f ${RADIOIDDB}.bz2
mv $RADIOIDDB $RADIOIDDB_TMP
# sort
## [已屏蔽] cat ${RADIOIDDB_TMP} | sort -un -k1n -o ${RADIOIDDB}
# 按第1列(DMR ID)数值升序去重：逗号分隔，仅以第1字段为键，数字从小到大排序后写回 user.csv
sort -t',' -k1,1n -u -o ${RADIOIDDB} ${RADIOIDDB_TMP}
rm -f $RADIOIDDB_TMP
# remove header
sed -i '1d' ${RADIOIDDB}

# commit!
rm -rf $base_dir/*bz2

echo "Committing new hostfiles..."
chmod a+r $base_dir/*
mv $base_dir/* /usr/local/etc/

# make link for legacy nextion configs
rm -rf ${STRIPPED}
rm -rf /usr/local/etc/stripped.csv
ln -s /usr/local/etc/user.csv /usr/local/etc/stripped.csv

touch /var/run/hostfiles-up # create/reset marker

if [ -t 1 ] ;
then
  echo -e "Update complete. All hostfiles have been refreshed."
else
  echo -e "* Update complete. All hostfiles have been refreshed. *"
fi

pattern="/usr/local/etc/stripped.csv.*"
files=($pattern)
if [ ${#files[@]} -gt 0 ]; then
  for file in "${files[@]}"; do
    rm -f "$file"
  done
fi

##结尾清理校验清单
rm -rf $base_dir/hostfile-checksums
exit 0
