#!/bin/bash -e
#
# 3cx configuration script


#--------------------------------------
#Verification des arguments "
#--------------------------------------
#
function usage(){
	echo 
	echo 
    echo "Usage : $0  <action>"
    echo "Actions disponibles : net | conf | purge | infos"
	echo 
	echo 
    exit 1
}

[ $# -eq 1 ] || usage
#--------------------------------------
# params
#--------------------------------------
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

log_file='/var/log/3cxInstall.log'
conf_dir='/etc'
grub_file="/etc/default/grub"
resolv_file="/etc/resolv.conf"
home_dir='/root'
conf_file="${home_dir}/3cx-template.txt"
netlock_file="${home_dir}/3cx/3cx-network.lock"
lock_file="${conf_dir}/3cx/3cx-setup.lock"
action=$1

#--------------------------------------
source  ${conf_file}
hostname=${FullExternalFqdn%%.*}
#-------------------------------------------------
# log
#--------------------------------------------------
function send_log() {
  LOG=$(date +"%x %X")
  echo "$LOG - $@" >>  ${log_file}
}

#-------------------------------------------------
# Modification reseau 
#--------------------------------------------------
function networkUpdate() {

	mkdir -p ${home_dir}/3cx
	if [ ! -f "${conf_file}" ] || [  -f "${netlock_file}" ]; then
	 msg=" le fichier ${conf_file} n'existe pas ou script deja excute "
	 echo $msg
	 send_log "$msg"
	 exit
	fi

	####
	send_log 'update: grub config'
	sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/' $grub_file
	update-grub

	echo 'nameserver 8.8.8.8' > $resolv_file
	echo 'nameserver 9.9.9.9' >> $resolv_file
	####
	send_log 'update: Network config'
	# gnupg2
	cat << EOF > ${conf_dir}/network/interfaces
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
auto eth0
iface eth0 inet static
	   address ${IpAddress}
	   netmask ${NetMask}
	   dns-nameservers ${NameServers}
	   gateway ${Gateway}
EOF
	#

	echo "k3cx-${hostname}" > ${conf_dir}/hostname
	echo "${IpAddress} k3cx-${hostname}" >> ${conf_dir}/hosts
	touch ${netlock_file}
	#
	history -c
	reboot
}


function getLetsEncryptCerts(){
	if [ ! -f "${conf_file}" ] || [  -f "${lock_file}" ] ; then
	 msg=" le fichier ${conf_file} n'existe pas ou script setup deja excute"
	 echo $msg
	 send_log "$msg"
	 exit
	fi


	cert=""
	key=""

	#################################
	cetGeneration=0
	# 1 Mois en Secondes= 2628000
	days="2628000"

	if [ -e "/etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem" ] && [ -e "/etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem" ] ; then
		send_log 'Certificate:  letsencrypt certificat existe'
		ret=$(openssl x509 -enddate -noout -in  /etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem  -checkend ${days} | tail -n 1 | grep -qi "Certificate will not expire" ;echo $?)
	    if [ "$ret" == "0" ] ;then
		cetGeneration=1
			send_log 'Certificate:  letsencrypt certificat existe et a une validee de plus d un mois'
		else
			send_log 'Certificate:  letsencrypt certificat existe et a une validee de moins d un mois'
	    fi
	fi

	if [ ${cetGeneration} -eq 0 ] ; then
		send_log 'Certificate: ajout letsencrypt certificat'
		send_log " /usr/bin/certbot certbot dry-run email : ${LicenseEmail}  domaine : ${FullExternalFqdn}"
		ret=`/usr/bin/certbot  certonly --key-type rsa --non-interactive --preferred-challenges http --standalone --agree-tos --renew-by-default --email ${LicenseEmail}  -d  ${FullExternalFqdn} --preferred-chain "ISRG Root X1" --dry-run `
		msg=$(echo $ret | cut -d '-' -f2)
		send_log "certbot dry-run RET: ${msg}"
		#IMPORTANT NOTES: - The dry run was successful.

		retcertbot=$(/usr/bin/grep -qi "successful" <<< $msg;echo $?)

		if [ "$retcertbot" == "0" ] ; then
		ret=`/usr/bin/certbot  certonly --key-type rsa --non-interactive --preferred-challenges http --standalone --agree-tos --renew-by-default --email  ${LicenseEmail}  -d ${FullExternalFqdn} --preferred-chain "ISRG Root X1" `
		send_log "create cert => certbot run RET: ${ret}"

			timeout=1500
			until [ -f  "/etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem" ]
			do
			if [ "$timeout" == 0 ]; then
				break
			fi
			sleep 2
			((timeout--))
			done
		fi
	fi
}
#--------------------------------------------------
# 3cx remove script
#--------------------------------------------------
function 3cxpurge() {
	if [  -f "${net_lock_file}" ] ; then
 		rm ${net_lock_file}
		echo "Supression du fichier de verrouillage réseau ..."
	fi

	if [  -f "${lock_file}" ] ; then
 		rm ${lock_file}
		echo "Supression du fichier de verrouillage 3cx ..."
	fi

	if [ $(dpkg-query -W -f='${Status}' 3cxpbx  2>/dev/null | grep -c "ok installed") -eq 1 ] ;
	then
		apt-get -y remove --purge 3cxpbx >> /dev/null 2>&1
		echo "Action : Purge de l'installation 3CX réalisée"
	fi
}
#---------------------------------------------------
function 3cxconfirm() {
    read -r -p "${1} [y/N] " response

    case "$response" in
        [yY][eE][sS]|[yY])
            true
            ;;
        *)
            false
            ;;
    esac
}
#---------------------------------------------------
function 3cxExecPurge(){

	if 3cxconfirm "A excuter en cas d'erreur d'installation. L'application 3CX sera supprimée s'elle est déjà installée. Pouvez-vous confirmer ?" ; then
		
		3cxpurge
	else
		echo "Annulation"
	fi
}

#---------------------------------------------------
# get system infos
#---------------------------------------------------
function getSysInfos(){
	memT=`grep MemTotal /proc/meminfo| awk '{print int($2/1000000) "G"}'`

	#CPU
	echo "---------------------------------------------------"
	echo "----- Système infos--------------------------------"
	echo "---------------------------------------------------"

	echo "Mémoire physique totale RAM : ${memT}"
	ncpu=`nproc --all`
	echo "Nombre de cœurs vCPU : ${ncpu}"
	#
	df -h | grep sda1 | awk '{print "Espace disque total : "$2 + 2 "G"}'
	echo "---------------------------------------------------"
}
#-------------------------------------------------------------------------------------------------
## Letsencrtpt, nginx et 3cx install 
#-------------------------------------------------------------------------------------------------

function 3cxSetupConfig() {
	#--------------------------------------------------
	# 3cx configuration script
	#--------------------------------------------------

	if [ ! -f "${conf_file}" ] || [  -f "${lock_file}" ] ; then
	 msg=" le fichier ${conf_file} n'existe pas ou script setup deja excute"
	 echo $msg
	 send_log "$msg"
	 exit
	fi

	cert=""
	key=""
	##########
	# update 
	apt-get -y remove 3cxpbx --purge
	apt-get -y remove nginx --purge
	apt-get -y  autoremove
	send_log 'apt-get autoremove'

	apt-get update
	apt-get -y upgrade
	send_log 'Install : vim certbot'
	apt-get -y install certbot vim
	#######################
	# 6_k3cxLetsencrypt -> get Let's Encrypt cert
	getLetsEncryptCerts &
	for job in `jobs -p`; do wait ${job}; done
	sleep 60
	######################

	if [ -f "/etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem" ] && [ -f "/etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem" ] ; then
	    send_log "letsencrypt: files ok"
	    cert=$(/usr/bin/cat /etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem)
	    key=$(/usr/bin/cat /etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem)
		until [ ! -z "${cert}" ] && [ ! -z "${key}" ]
		do
			send_log "letsencrypt: Empty File =>  ${cert} &/| ${key}"
			cert=$(/usr/bin/cat /etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem)
			key=$(/usr/bin/cat /etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem)
		sleep 1
		done
	fi


	cat <<EOF >  /lib/systemd/system/aocertrenew.service
[Unit]
Description=3cx letsencrypt renew
After=network.target
Wants=aocertrenew.timer

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/aocertrenew
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

	cat <<EOF >  /lib/systemd/system/aocertrenew.timer
[Unit]
Description=run 3cx script letsencrypt renew
Requires=aocertrenew.service

[Timer]
OnCalendar=monthly

[Install]
WantedBy=timers.target
EOF


#-----------------------------------------------------
	cat <<EOF > /usr/local/sbin/aocertrenew
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

/usr/bin/certbot  certonly --key-type rsa --non-interactive --preferred-challenges http --standalone --agree-tos --renew-by-default --email ${LicenseEmail} -d ${FullExternalFqdn}  --preferred-chain "ISRG Root X1"; ret=\$?
if [ "\$ret" == "0" ] ; then

    if [ -f "/var/lib/3cxpbx/Bin/nginx/conf/Instance1/domain_key_${FullExternalFqdn}.pem" ] && [ -f "/var/lib/3cxpbx/Bin/nginx/conf/Instance1/domain_cert_${FullExternalFqdn}.pem" ] ; then
        cp -u /etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem /var/lib/3cxpbx/Bin/nginx/conf/Instance1/domain_cert_${FullExternalFqdn}.pem
        cp -u /etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem /var/lib/3cxpbx/Bin/nginx/conf/Instance1/domain_key_${FullExternalFqdn}.pem
        service  nginx reload
    fi
fi

EOF

#--------------------------------------------------

	chmod +x /usr/local/sbin/aocertrenew
	systemctl enable aocertrenew.service
	systemctl enable aocertrenew.timer
	systemctl --system daemon-reload
	systemctl start aocertrenew.service
	systemctl start aocertrenew.timer

	send_log 'creation rep /etc/3cxpbx'
	mkdir -p /etc/3cxpbx

	send_log "`ls -1 /etc/3cxpbx`"

#--------------------------------------------------------------------------------
	cat << EOF > /etc/3cxpbx/setupconfig.xml
<?xml version='1.0' encoding='utf-8'?>
<SetupConfig xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <tcxinit>
    <option> <code>InstallationType</code> <answer>new</answer> </option>
    <option> <code>LicenseKey</code> <answer>${LicenseKey}</answer> </option>
    <option> <code>AdminUsername</code> <answer>Koesiotelecom</answer> </option>
    <option> <code>AdminPassword</code> <answer>Koesio1..1</answer> </option>
    <option> <code>PublicIP</code> <answer>auto</answer> </option>
    <option> <code>ManualPublicIP</code> <answer> </answer> </option>
    <option> <code>StaticOrDynamicIP</code> <answer>static</answer> </option>
    <option> <code>LocalIP</code> <answer>auto</answer> </option>
    <option> <code>NeedFqdn</code> <answer>no</answer> </option>
    <option> <code>Hostname</code> <answer>k3cx-${hostname}</answer> </option>
    <option> <code>DomainGroup</code> <answer>Europe</answer> </option>
    <option> <code>DnsSuffix</code> <answer>29</answer> </option>
    <option> <code>FullExternalFqdn</code> <answer>${FullExternalFqdn}</answer> </option>
    <option> <code>CertificatePath</code> <answer>$(</etc/letsencrypt/live/${FullExternalFqdn}/fullchain.pem)</answer> </option>
    <option> <code>CertificatePassword</code> <answer> </answer> </option>
    <option> <code>CertificateKey</code> <answer>$(</etc/letsencrypt/live/${FullExternalFqdn}/privkey.pem)</answer> </option>
    <option> <code>CertificateKeyPasswordRequest</code> <answer> </answer> </option>
    <option> <code>HasLocalDns</code> <answer>yes</answer> </option>
    <option> <code>InternalFqdn</code> <answer>${FullExternalFqdn}</answer> </option>
    <option> <code>HttpsPort</code> <answer>443</answer> </option>
    <option> <code>HttpPort</code> <answer>5000</answer> </option>
    <option> <code>SipPort</code> <answer>5060</answer> </option>
    <option> <code>TunnelPort</code> <answer>5090</answer> </option>
    <option> <code>NumberOfExtensions</code> <answer>${NumberOfExtensions}</answer> </option>
    <option> <code>AdminEmail</code> <answer>${AdminEmail}</answer> </option>
    <option> <code>MailServerType</code> <answer>3CX</answer> </option>
    <option> <code>MailServerAddress</code> <answer> </answer> </option>
    <option> <code>MailServerReplyTo</code> <answer>${MailServerReplyTo}</answer> </option>
    <option> <code>MailServerEnableSslTls</code> <answer>yes</answer> </option>
    <option> <code>Continent</code> <answer>Europe</answer> </option>
    <option> <code>Country</code> <answer>France</answer> </option>
    <option> <code>Timezone</code> <answer>45</answer> </option>
    <option> <code>OperatorVoicemail</code> <answer>${OperatorVoicemail}</answer> </option>
    <option> <code>Language</code> <answer>FR</answer></option>
    <option> <code>Promptset</code> <answer>French</answer> </option>
    <option> <code>LicenseContactName</code> <answer>${LicenseContactName}</answer> </option>
    <option> <code>LicenseCompanyName</code> <answer>${LicenseCompanyName}</answer> </option>
    <option> <code>LicenseEmail</code> <answer>${LicenseEmail}</answer> </option>
    <option> <code>LicensePhone</code> <answer>${LicensePhone}</answer> </option>
    <option> <code>ResellerId</code> <answer> </answer> </option>
  </tcxinit>
  <extensions>
      <extension>
        <Number>${Extension}</Number>
        <FirstName>Koesio</FirstName>
        <LastName></LastName>
        <EmailAddress>${SupportEmail}</EmailAddress>
        <MobileNumber></MobileNumber>
        <OutboundCallerId></OutboundCallerId>
        <AuthPassword>NK54qn0FuZ5D</AuthPassword>
        <AuthID>YR21vax3qcMf</AuthID>
        <AllowLanOnly>false</AllowLanOnly>
        <RecordCalls>false</RecordCalls>
        <Codecs></Codecs>
        <Language>French</Language>
        <ProvisionType>LocalLan</ProvisionType>
     </extension>
     <extension>
        <Number>${OperatorExtension}</Number>
        <FirstName>Standard</FirstName>
        <LastName></LastName>
        <EmailAddress>a-${OperatorEmail}</EmailAddress>
        <MobileNumber></MobileNumber>
        <OutboundCallerId></OutboundCallerId>
        <AuthPassword>NK54qn0F45FG</AuthPassword>
        <AuthID>LK45FGvghYJ</AuthID>
        <AllowLanOnly>false</AllowLanOnly>
        <RecordCalls>false</RecordCalls>
        <Codecs></Codecs>
        <Language>French</Language>
        <ProvisionType>LocalLan</ProvisionType>
     </extension> 
  </extensions>
<siptrunk>
        <Name>Koesio Enove</Name>
        <TemplateFilename>koesio.pv.xml</TemplateFilename>
        <Host>trunk.enove.fr</Host>
        <Port>5060</Port>
        <ProxyHost>trunk.enove.fr</ProxyHost>
        <ProxyPort>5060</ProxyPort>
        <SimultaneousCalls>${SimultaneousCalls}</SimultaneousCalls>
        <RequireRegistrationFor>InOutCalls</RequireRegistrationFor>
        <AuthID>XXXX${SipTrunkID}</AuthID>
        <AuthPassword>${SipTrunkPWD}</AuthPassword>
        <Use3WayAuth>false</Use3WayAuth>
        <ExternalNumber>${SipTrunkID}</ExternalNumber>
        <OfficeHoursDestinationType>Extension</OfficeHoursDestinationType>
        <OfficeHoursDestination>${OperatorExtension}</OfficeHoursDestination>
        <OutOfOfficeHoursDestinationType>Extension</OutOfOfficeHoursDestinationType>
        <OutOfOfficeHoursDestination>${OperatorExtension}</OutOfOfficeHoursDestination>
        <DIDNumbers></DIDNumbers>
        <OutboundCallerID></OutboundCallerID>
        <Direction>Both</Direction>
        <DeliverAudio>true</DeliverAudio>
        <DisableVideoCalls>true</DisableVideoCalls>
        <SupportReinvite>false</SupportReinvite>
        <SupportReplaces>false</SupportReplaces>
        <PublicIpInSipViaHeader></PublicIpInSipViaHeader>
        <EnableSRTP>false</EnableSRTP>
        <TimeBetweenReg>120</TimeBetweenReg>
        <IPInRegistrationContact>Default</IPInRegistrationContact>
        <SpecifiedIPForRegistrationContact></SpecifiedIPForRegistrationContact>
        <IPMode></IPMode>
        <Codecs>
		<codec>PCMA</codec>
		<codec>G729</codec>
	</Codecs>
    </siptrunk>
<OutboundRules>
   <OutboundRule>
      <Name>0</Name>
      <Prefix>0</Prefix>
      <DNRanges><DNRange><To></To><From></From></DNRange></DNRanges>
      <NumberLengthRanges></NumberLengthRanges>
      <DNGroups><Group></Group></DNGroups>
      <OutboundRoutes>
            <OutboundRoute><Gateway>Koesio Enove</Gateway><StripDigits>0</StripDigits><Prepend></Prepend></OutboundRoute>
      </OutboundRoutes>
   </OutboundRule>

   <OutboundRule>
      <Name>00</Name>
      <Prefix>00</Prefix>
      <DNRanges><DNRange><To></To><From></From></DNRange></DNRanges>
      <NumberLengthRanges></NumberLengthRanges>
      <DNGroups><Group></Group></DNGroups>
      <OutboundRoutes>
            <OutboundRoute><Gateway>Koesio Enove</Gateway><StripDigits>0</StripDigits><Prepend></Prepend></OutboundRoute>
      </OutboundRoutes>
   </OutboundRule>

   <OutboundRule>
      <Name>+33</Name>
      <Prefix>+33</Prefix>
      <DNRanges><DNRange><To></To><From></From></DNRange></DNRanges>
      <NumberLengthRanges></NumberLengthRanges>
      <DNGroups><Group></Group></DNGroups>
      <OutboundRoutes>
            <OutboundRoute><Gateway>Koesio Enove</Gateway><StripDigits>0</StripDigits><Prepend></Prepend></OutboundRoute>
      </OutboundRoutes>
   </OutboundRule>

   <OutboundRule>
      <Name>1-9</Name>
      <Prefix>1-9</Prefix>
      <DNRanges><DNRange><To></To><From></From></DNRange></DNRanges>
      <NumberLengthRanges></NumberLengthRanges>
      <DNGroups><Group></Group></DNGroups>
      <OutboundRoutes>
            <OutboundRoute><Gateway>Koesio Enove</Gateway><StripDigits>0</StripDigits><Prepend></Prepend></OutboundRoute>
      </OutboundRoutes>
   </OutboundRule>

   <OutboundRule>
      <Name>+</Name>
      <Prefix>+</Prefix>
      <DNRanges><DNRange><To></To><From></From></DNRange></DNRanges>
      <NumberLengthRanges></NumberLengthRanges>
      <DNGroups><Group></Group></DNGroups>
      <OutboundRoutes>
            <OutboundRoute><Gateway></Gateway><StripDigits>0</StripDigits><Prepend></Prepend></OutboundRoute>
      </OutboundRoutes>
   </OutboundRule>
</OutboundRules>
    <IpBlackList>
	<IpBlackListEntry>
	<Address>91.216.43.225</Address>
	<Mask>255.255.255.255</Mask>
	<Allowed>true</Allowed> <Description>IP KOESIO AURA</Description> </IpBlackListEntry>
     </IpBlackList>
</SetupConfig>
EOF

#------------------------------------------------
	send_log 'Install : 3cxpbx apt-get update'
	echo "deb [arch=$(dpkg --print-architecture) by-hash=yes signed-by=/usr/share/keyrings/3cx-archive-keyring.gpg] http://repo.3cx.com/3cx bookworm main" | tee /etc/apt/sources.list.d/3cxpbx.list
	cat << EOF > /etc/apt/sources.list
deb http://deb.debian.org/debian bookworm main non-free-firmware
deb-src http://deb.debian.org/debian bookworm main non-free-firmware

deb http://security.debian.org/debian-security bookworm-security main non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main non-free-firmware

deb http://deb.debian.org/debian bookworm-updates main non-free-firmware
deb-src http://deb.debian.org/debian bookworm-updates main non-free-firmware
EOF

	apt-get update
	apt-get -y upgrade
	send_log 'autoremove purge : 3cxpbx, nginx'
	#4_k3cxCheckDisk
	apt-get -y install nginx
	rm -f /etc/nginx/sites-enabled/default
	rm -f /tmp/3cxpbx.sync
	systemctl reload nginx
	apt-get -y install 3cxpbx
	# get sys info 
	getSysInfos

} 

#------------------------------------------------------------------------------
# actions
#------------------------------------------------------------------------------
case "$action" in

"net")
	networkUpdate

	;;
"conf")
	3cxSetupConfig
	;;
"purge")
	3cxExecPurge

	;;
"infos")
	getSysInfos

	;;

 # Action non reconnue
    *)
    usage
        ;;
esac
