#!/bin/bash

. ${TOOLKIT}-functions.sh

set -e -u


add_share()
{
	local share=$1
	local desc=$2
	local wide_links=$3
	local abe_access=$4
	shift 4
	local opts="$@"
	local name=
	local path=
	local inline_opts=

	if echo "$share" | grep -q ","
	then
		path=$(echo "$share" | cut -d',' -f1)
		inline_opts=$(echo "$share" | sed -e "s}^$path,}}")
	else
		path="$share"
	fi

	if echo "$path" | grep -q "="
	then
		name=$(echo "$path" | cut -d'=' -f1)
		path=$(echo "$path" | sed -e "s}^$name=}}")
	else
		name=$(basename "$path")
	fi

	grep -q "^$name$" $done && {
		echo "  WARN: ignoring duplicate share name '$name'"
		return 1
	}

	printf "  share: %-12s on %-20s " "$name" "$path"

	echo "[$name]"				>>$outfile
	echo "  path = $path"			>>$outfile
	echo "  comment = $desc"		>>$outfile
	echo "  wide links = $wide_links"	>>$outfile
	echo "  access based share enum = $abe_access" >>$outfile
	[ "X$opts" != "X" ] && {
	    echo -e "$opts" 			>>$outfile
	}

	local opt=
	local arg=

	for opt in $(echo "$inline_opts" | tr ',' ' ')
	do
	    case $opt in
	      GROUP:*)	arg=$(echo "$opt" | cut -d':' -f2)
	      		echo "  force group = +$arg" >>$outfile
			;;
	      USER:*)	arg=$(echo "$opt" | cut -d':' -f2)
	      		echo "  force user = +$arg" >>$outfile
			;;
	      *)	echo "  $opt" >>$outfile
	      		;;
	    esac
	done

	if [ -d $path ]
	then
		echo "(ok)"
	else
		echo "  WARN! path not existent!"
	fi
	
	echo "$name" >>$done
	return 0
}




myself=$(uname -n)
myself_short=$(uname -n | sed -e 's/\..*//')



# SANITY CHECKS

needs_guest=false
jtconf samba.pub_shares 2>/dev/null >/dev/null && needs_guest=true
jtconf samba.open_shares 2>/dev/null >/dev/null && needs_guest=true

$needs_guest && {
	guest=$(jtconf samba.guest_user)	|| exit_missing_define samba.guest_user

	[ "$guest" = "Bad User" ] && {
		putwarning "samba guest user" \
			"you have some shares declared as Guest, but your" \
			"guest user is now set to '$guest', please use a real" \
			"one in 'samba.guest_users' variable"
		exit 1
	}
}


# BUILD SAMBA CONFIG FILE

outfile="smb.conf.tmp"
done="done.tmp"
cp /dev/null $done


# --- COMMMON (GLOBALS) -------------------------------------------------------

# base config file
file=$(filepath smb.conf-base) || exit_err 1 "can't find smb.conf-base"
cat $file >>$outfile


# optional global parms
#
echo -e "\t# optional parms\n" >>$outfile
for var in	wins_server \
		directory_mask create_mask force_directory_mode force_create_mode \
		map_archive map_hidden
do
	value=$(jtconf samba.$var 2>/dev/null) || continue
	[ "$value" == "" ] && continue
	key=$(echo "$var" | tr '_' ' ')
	echo "	$key = $value" >>$outfile
done

# check for obsoleted values
value=$(jtconf samba.directory_mode 2>/dev/null) && {
	[ "$value" != "" ] && {
		exit_err 1 "samba.directory_mode obsoleted, use samba.force_directory_mode instead"
	}
} || :
value=$(jtconf samba.create_mode 2>/dev/null) && {
	[ "$value" != "" ] && {
		exit_err 1 "samba.create_mode obsoleted, use samba.force_create_mode instead"
	}
} || :



# domain master yes/no?
#
file="smb.conf-no-master-domain"
getconfirm samba.domain_master && {
	echo "  enabling Domain Master"
	file="smb.conf-master-domain"
}
path=$(filepath $file) || exit_err 1 "can't find $file"
cat $path >>$outfile


# ldap support yes/no?
#
file="smb.conf-no-ldap"

case $DISTRIB_ID in
  Devuan)
	getconfirm samba.ldap && {
  		echo "  WARNING: LDAP backend not available on samba4"
	}
	;;
  *)
	getconfirm samba.ldap && {
		echo "  enabling LDAP backend"
		if service_requested ldap
		then
			file="smb.conf-ldap"
		else
			putwarning "SAMBA / LDAP" \
				"you have requested LDAP backend in Samba, but you don't have" \
				"ldap service enabled in kusa (services)"
		fi
	}
	;;
esac
path=$(filepath $file) || exit_err 1 "can't find $file"
cat $path >>$outfile




# --- SHARES -------------------------------------------------------------------------------

# netlogons?
#
getconfirm samba.domain_master && {
	echo "  share: Netlogon & Profiles"
	file=$(filepath smb.conf-netlogon) || exit_err 1 "can't find smb.conf-netlogon"
	cat $file >>$outfile
}


# homedirs?
#
getconfirm samba.share_homes && {
	echo "  share: Homes"
	file=$(filepath smb.conf-homes) || exit_err 1 "can't find smb.conf-homes"
	cat $file >>$outfile
}


# printers
#
getconfirm samba.share_print && {
	echo "  share: Print"
	file=$(filepath smb.conf-printers) || exit_err 1 "can't find smb.conf-printers"
	cat $file >>$outfile
}


# automatic shares (rapid shares)

# get defaults from samba_share section
#
default_opts=$(jtconf samba_share.opts 2>/dev/null || :)
wide_links=$(jtconf samba_share.wide_links 2>/dev/null || :)
abe_access=$(jtconf samba_share.abe_access 2>/dev/null || :)
opts=

# rapid (standard)
#
for share in $(jtconf samba.rapid_shares 2>/dev/null || :)
do
	add_share $share "" "$wide_links" "$abe_access" "$default_opts"
done

# pub (guest ok & read-only)
#
for share in $(jtconf samba.pub_shares 2>/dev/null || :)
do
	opts="  guest ok = yes\n  read only = yes"
	[ "$default_opts" != "" ] && opts="$default_opts\n$opts"
	add_share $share "(pub)" "$wide_links" "No" "$opts"
done

# open (guest ok & READ/WRITE (!)
#
for share in $(jtconf samba.open_shares 2>/dev/null)
do
	opts="  guest ok = yes\n"
	[ "$default_opts" != "" ] && opts="$default_opts\n$opts"
	add_share $share "(open)" "$wide_links" "No" "$opts"
done

# readonly
#
for share in $(jtconf samba.ro_shares 2>/dev/null)
do
	opts="  read only = yes"
	[ "$default_opts" != "" ] && opts="$default_opts\n$opts"
	add_share $share "" "$wide_links" "$abe_access" "$opts"
done

# 2020-08-11 lc
# - samba.share.* --> samba_share.*
#
check_old_format=$(jtconf --list samba.share. || :)
[ "X$check_old_format" != "X" ] && {
	echo -e "\n  OBSOLETE SHARE DEFINITIONS FOUND:\n\n" $check_old_format "\n"

	exit_err 1 "
  since 2020-08-11 the samba shares are no more under 'samba.share'
  section, you need to move them to 'samba_share' one (replace the dot
  whith an underscore)
"
	echo
	exit 1
}


# scan samba_shares.* for this host
#
for share in $(jtconf --list samba_share.)
do
	# server list defined?
	#
	if servers=$(jtconf $share.servers 2>/dev/null)
	then
		add_share=false
		for srv in $(echo $servers | tr ',' ' ')
		do
			[ $srv = $myself -o $srv = $myself_short ] && {
				add_share=true
				break
			}
		done
	else
		add_share=true
	fi
	$add_share || continue	# not for me

	name=$(jtconf $share.name 2>/dev/null || :)
	path=$(jtconf $share.path) || exit $?
	desc=$(jtconf $share.desc 2>/dev/null || :)
	opts=$(jtconf $share.opts 2>/dev/null || :)
	wide=$(jtconf $share.wide_links 2>/dev/null || :)
	abe=$(jtconf $share.abe_access 2>/dev/null || :)

	[ "$name" ] || {
		name=$(echo $share | sed -e 's/^samba_share\.//')
	}

	add_share "${name}=$path" "$desc" "$wide" "$abe" "$opts"
done

# machine overrides
#
file=$(filepath smb.conf-machine-overrides) || exit_err 1 "can't find smb.machine-overrides"
cat $file >>$outfile


# latest, add local customizations (id any)
#
file=$(filepath smb.conf.local) && {
	echo -e "  adding custom settings $file"
	cat $file >>$outfile
}

exit 0
