#!/usr/local/bin/cbsd
#v12.1.17
MYARG=""
MYOPTARG="bootstrap config debug_form export formfile group groupname header index inter jname module out table updcol"
MYDESC="Assistant for configuring containers/services, TUI/CLI"
ADDHELP="
${H3_COLOR}Description${N0_COLOR}:

 CBSD forms represents a bridge between user parameters and helper for the jail environment.
 Unlike templates that usually contain static packages/config files, you can use the full power 
 of dynamic configurations (Puppet,Ansible,SaltStack,Chef) using the community force.
 This allows you to configure the setting not only at the initial start, but also accompany and 
 reconfigure the service at any time.

 By running 'cbsd forms jname=XXXX module=NNN', you will dynamically built forms in TUI and can
 view/modify and apply settings. If you prefer non-interactive configuration and/or want to overwrite
 settins, you can use:

   - external helper (e.g. with consul/zookeeper/... integration);
   - config file with (~cbsd/etc/forms_env.conf by default) with ( H_<param>=\"<value>\" settings );
   - global variable via H_<param>=\"<value>\" env;

After forms apply, you can export current helper settings via external helper (e.g. with 
consul/zookeeper/... integration) or to local file with default variable form:

<jname>_<module>_PARAM="values"

This form can be mapped/overwrited at your discretion via global forms_export_vars.conf or
per-jail in ~cbsd/jails-system/jail/etc/forms_export_vars.conf.

When 'cbsd forms' executed with 'vars' args: show VARIABLE names per module.

${H3_COLOR}Options${N0_COLOR}:

 ${N2_COLOR}config=${N0_COLOR} - read H_<params> values from this file,
           default values: ~cbsd/etc/forms_env.conf
 ${N2_COLOR}export=${N0_COLOR} - export variables;
 ${N2_COLOR}jname=${N0_COLOR}  - jail name to configure, with reserved name:
           if jname name is 'cbsdpuppet1' then just generate manifest or hiera.
           if jname name is CBSDSYS then configure current system.
 ${N2_COLOR}index=${N0_COLOR}  - index id for group_add and group_del operation;
 ${N2_COLOR}group=${N0_COLOR}  - group=add or group=del to add/del custom params group, 
             in dynamical forms;
 ${N2_COLOR}out=${N0_COLOR}    - out manifest content to file, when jname=cbsdpuppet1;
 ${N2_COLOR}table=${N0_COLOR}  - initial table, default is forms;
 ${N2_COLOR}updcol=${N0_COLOR} - 'new' (default) update 'new' value, 'cur' - update 'cur' value;

${H3_COLOR}Examples${N0_COLOR}:

 # cbsd jcreate jname=redis runasap=1
 # cbsd module mode=install forms-redis
 # cbsd forms module=redis jname=redis
 # env H_port=1234 H_maxmemory=8g cbsd forms module=redis jname=redis inter=0
 # cbsd forms module=redis vars

${H3_COLOR}See also${N0_COLOR}:

 cbsd repo --help

"
CBSDMODULE="jail"
EXTHELP="wf_forms"

. ${subrdir}/nc.subr
. ${tools}	# forms
. ${strings}	# forms
. ${system}

[ ! -d "${workdir}" ] && err 1 "${N1_COLOR}No such workdir: ${N2_COLOR}${workdir}${N0_COLOR}"

if [ "${1}" != "--help" -a "${1}" != "--args" ]; then
	# assume that this is the path to form when path geing with slash
	prefix=$( substr --pos=0 --len=1 --str=${1} )
	if [ "${prefix}" = "/" ]; then
		formfile="${1}"
		[ ! -f "${1}" ] && err 1 "${N1_COLOR}No such form file: ${N2_COLOR}${formfile}${N0_COLOR}"
		shift
		param=$( cbsdsqlro ${formfile} SELECT param FROM forms ORDER BY CAST\(order_id AS int\) | ${XARGS_CMD} )
		MYOPTARG="${MYOPTARG} ${param}"
	fi
fi

groupname=
debug_form=0
config="forms_env.conf"
oupdcol=
updcol=
export=
oexport=
show_vars_only=0
for i in $*; do
	[ "${i}" = "vars" ] && show_vars_only=1
done

. ${cbsdinit}
[ -n "${updcol}" ] && oupdcol="${updcol}"
[ -z "${updcol}" ] && updcol="new"
[ -n "${export}" ] && oexport="${export}"
[ -z "${export}" ] && export="stdout"
[ -n "${groupname}" ] && ogroupname="${groupname}"

. ${subrdir}/settings-tui.subr
. ${dialog}

[ -z "${table}" ] && table="forms"

if [ -n "${header}" ]; then
	shift
else
	header=1
fi

readconf helpers.conf
. ${subrdir}/imghelper.subr

selected_defaultitem=

dialog_menu_main()
{
	local _par VAL
	local btitle="$DIALOG_BACKTITLE"
	local prompt="Use menu to select and edit items"
	local hline=
	local mytargets=
	local defaultitem=

	f_dialog_default_fetch defaultitem

	[ -n "${selected_defaultitem}" ] && defaultitem="${selected_defaultitem}"
	[ -n "${jname}" ] && mytargets="for ${jname} "

	local title
	local _mydesc
	local menu_list=
	local _id=0 _delimer_check

	if [ -n "${forms_title}" ]; then
		title="${forms_title}"
	else
		title=" Image parameters ${mytargets}"
	fi

	for _items in ${param}; do

		_id=$(( _id + 1 ))

		unset VAL _type
		is_value=0
		is_delimer=0

		_delimer_check=$( substr --pos=0 --len=1 --str="${_items}" )

		if [ "${_delimer_check}" = "-" ]; then
			_type="delimer"
		else
			eval _type="\$${_items}_type"
		fi

		case "${_type}" in
			subtable)
				VAL=">>"
				;;
			hiddendelim)
				continue
				;;
			delimer)
				_items="forms_delimer_${_id}"
				is_delimer=1
				;;
			group_add)
				VAL="+"
				;;
			*)
				eval VAL=\$${_items}
				is_value=1
				;;
		esac

		eval _mydesc="\|\$${_items}_desc\|"
		eval _xattr="\$${_items}_xattr"
		[ "${_xattr}" = "dynamic" ] && _mydesc="${_mydesc} [*dynamic*, can be deleted]"

		if [ ${is_delimer} -eq 1 ]; then
			menu_list="${menu_list} ''		'${_mydesc}'	'Field delimer'"
		elif [ -z "${VAL}" ]; then
			menu_list="${menu_list} '${_items}'	' '		'${_mydesc}'"
		else
			menu_list="${menu_list} '${_items}'	'${VAL}'	'${_mydesc}'"
		fi

	done

	menu_list="${menu_list} 'COMMIT'	'Save changes and quit'	'Save!'"

	#cbsd_menubox
	extra_label="Delete"
	cbsd_menubox_with_extra_button
	retval=$?

	f_dialog_data_sanitize menu_choice
	f_dialog_menutag_store "$menu_choice"
	f_dialog_default_store "$menu_choice"

	return $retval
}


# $1 table
get_radio()
{
	local param
	local table="${1}"

	[ -z "${table}" ] && return 1

	param_list=$( cbsdsqlro ${formfile} SELECT text FROM ${table} ORDER BY CAST\(order_id AS int\) | ${XARGS_CMD} )
	local menu_list=
	local x=0
	local _par VAL
	local btitle="$DIALOG_BACKTITLE"
	local prompt="Use menu for select"
	local hline=
	local defaultitem
	defaultitem="yes"

	local title=" ${table} "
	local _mydesc

	local menu_list=
	for item in ${param_list}; do
		eval _mydesc="\$${helper}_desc"
		menu_list="${menu_list} '${item}'	'${item}'	'${_mydesc}'"
	done

	cbsd_menubox
	retval=$?

	mtag=$( cbsdsqlro ${formfile} SELECT text FROM ${table} WHERE text=\"${menu_choice}\" )
	f_dialog_data_sanitize menu_choice

	return $retval
}


# $1 table
get_checkbox()
{
	local param
	local table="${1}"

	[ -z "${table}" ] && return 1

	param_list=$( cbsdsqlro ${formfile} SELECT text FROM ${table} ORDER BY CAST\(order_id AS int\) | ${XARGS_CMD} )
	local menu_list=
	local x=0
	local _par VAL
	local btitle="$DIALOG_BACKTITLE"
	local prompt="Use menu for select"
	local hline=
	local defaultitem

	local title=" syslog "
	local _mydesc

	local menu_list=

	while [ 1 ]; do

		menu_list=

		for i in ${param_list}; do
			eval _mytest=\$$i
			if [ "${_mytest}" = "1" ]; then
				export ${i}_mark="X"
			else
				export ${i}_mark=" "
			fi
		done

		for item in ${param_list}; do
			eval _mydesc="\$${helper}_desc"
			eval _mytest=\$${item}_mark
			[ -z "${_mytest}" ] && _mytest=" "
			menu_list="${menu_list}	'${item}'	'[${_mytest}]'	'${_mydesc}'"
		done

		menu_list="${menu_list}	'SELECT'	''	'Select items'"

		cbsd_menubox || return 0

		retval=$?

		index=${mtag%% *}
		mychoice=${mtag##* }

		case "${mychoice}" in
			"SELECT")
				mtag=
				local num=0
				for i in ${param_list}; do
					eval _mytest=\$$i
					if [ "${_mytest}" = "1" ]; then
						if [ ${num} -eq 0 ]; then
							mtag="${i}"
						else
							mtag="${mtag} ${i}"
						fi
						num=$(( num + 1 ))
					fi
				done
#				printf "${mtag}"
				return 0
			;;
			-)	# delimer field
				continue
				;;
			*)
				eval _mytest=\$$mychoice
				if [ ${_mytest} = "1" ]; then
					export ${mychoice}="0"
				else
					export ${mychoice}="1"
				fi
				defaultitem="${mychoice}"
				;;
		esac
	done

	mtag=$( cbsdsqlro ${formfile} SELECT id FROM ${table} WHERE text=\"${menu_choice}\" )

	return ${retval}
}

reload_forms_full()
{
	local sql_part="SELECT param FROM ${table} WHERE type != \"subtable\" ORDER BY CAST(order_id AS int)"
	param=$( cbsdsqlro ${formfile} ${sql_part} )
	load_forms
	load_new
}


# INDEX (namespace)
get_group_id()
{
	local _new _group_id _new_group_id

	while getopts "a:g:" opt; do
		case "${opt}" in
			a) action="${OPTARG}" ;;
			g) groupname="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	if [ ! -r "${formfile}" ]; then
		echo "get_group_id: formfile not readable: ${formfile}"
		return 1
	fi

	if [ -z "${action}" ]; then
		echo "get_group_id: formfile not readable: ${formfile}"
		return 1
	fi

	_new_group_id=$( ${SQLITE3_CMD} ${formfile} "SELECT group_id FROM forms ORDER BY group_id DESC LIMIT 1" )
	#echo "${SQLITE3_CMD} ${formfile} \"SELECT group_id FROM forms ORDER BY group_id DESC LIMIT 1\"" > /tmp/forms.txt
	#echo "N: ${_new_group_id}" >> /tmp/forms.txt

	if [ -z "${_new_group_id}" ]; then
		printf "get_group_id: empty new_group_id: SELECT group_id FROM forms WHERE groupname = '${groupname}'"
		return 1
	fi

	case "${action}" in
		add|create)
			_group_id=$(( _new_group_id + 1 ))
			;;
		del*|remove)
			_group_id=${_new_group_id}
			;;
	esac

	if [ -z "${_group_id}" ]; then
		echo "get_group: empty _group_id: ${formfile}"
		return 1
	fi

	printf "${_group_id}"
}

get_order_id()
{
	local _new _order_id _new_order_id

	while getopts "a:g:" opt; do
		case "${opt}" in
			a) action="${OPTARG}" ;;
			g) groupname="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	if [ ! -r "${formfile}" ]; then
		echo "get_order_id: formfile not readable: ${formfile}"
		return 1
	fi

	if [ -z "${action}" ]; then
		echo "get_order_id: formfile not readable: ${formfile}"
		return 1
	fi

	_new_order_id=$( ${SQLITE3_CMD} ${formfile} "SELECT order_id FROM forms WHERE groupname = '${groupname}' ORDER BY order_id DESC LIMIT 1" )
#	echo "${SQLITE3_CMD} ${formfile} \"SELECT order_id FROM forms WHERE groupname = '${groupname}' ORDER BY order_id DESC LIMIT 1\"" >> /tmp/forms.txt
#	echo "N: ${_new_order_id}" >> /tmp/forms.txt

	if [ -z "${_new_order_id}" ]; then
		printf "get_order_id: empty new_order_id: SELECT order_id FROM forms WHERE groupname = '${groupname}'"
		return 1
	fi

	case "${action}" in
		add|create)
			_order_id=$(( _new_order_id + 1 ))
			;;
		del*|remove)
			_order_id=${_new_order_id}
			;;
	esac

	if [ -z "${_order_id}" ]; then
		echo "get_order: empty _order_id: ${formfile}"
		return 1
	fi

	printf "${_order_id}"
}

group_add()
{
	local _config= _file= _group_id= _order_id= _res= _ret=

	while getopts "c:g:o:" opt; do
		case "${opt}" in
			c) _config="${OPTARG}" ;;
			g) _group_id="${OPTARG}" ;;
			o) _order_id="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	# index/sequence
	if [ -z "${_group_id}" ]; then
		_res=$( get_group_id -a add -g ${_config} 2>&1 )
		_ret=$?
		[ ${_ret} -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP} error: ${_res}${N0_COLOR}"
		_group_id="${_res}"
	fi

	if [ -z "${_order_id}" ]; then
		_res=$( get_order_id -a add -g ${_config} 2>&1 )
		_ret=$?
		[ ${_ret} -ne 0 ] && err 1 "${N1_COLOR}${CBSD_APP} error: ${_res}${N0_COLOR}"
		_order_id="${_res}"
	fi

	_file="${distmoduledir}/forms.d/${module}/custom_${_config}.sh"
	[ ! -x ${_file} ] && err 1 "${N1_COLOR}forms not support for dynamic data, no such: ${N2_COLOR}${_file}${N0_COLOR}"
	#echo "${_file} -a add -i ${_group_id} -o ${_order_id} -f ${formfile}"

	_res=$( ${_file} -a add -i ${_group_id} -o ${_order_id} -f ${formfile} 2>&1 )
	_ret=$?
	if [ ${_ret} -ne 0 ]; then
		err 1 "${N1_COLOR}${CBSD_APP} error: group_add: ${_res}${N0_COLOR}"
	fi

	return 0
}

# $1 - overvrite index
group_del()
{
	local _config _file _order_id

	while getopts "c:o:" opt; do
		case "${opt}" in
			c) _config="${OPTARG}" ;;
			o) _order_id="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	_file="${distmoduledir}/forms.d/${module}/custom_${_config}.sh"

	[ ! -x ${_file} ] && err 1 "${N1_COLOR}forms not support for dynamic data, no such: ${N2_COLOR}${_file}${N0_COLOR}"
	${_file} -a del -o ${_order_id} -f ${formfile}
}


# inputform
get_helper_value()
{
	local _input _retval _xattr _type _link _mtag _group_id _delete=0

	[ "${1}" = "delete" ] && _delete=1

	f_dialog_title " ${mtag} "

	eval VAL=\$${mtag}
	eval _mydesc=\$${mtag}_desc
	eval _type=\$${mtag}_type
	eval _link=\$${mtag}_link
	eval _xattr=\$${mtag}_xattr
	eval _group_id=\$${mtag}_group_id

	if [ ${_delete} -eq 1 ]; then
		if [ "${_xattr}" != "dynamic" ]; then
			f_dialog_msgbox "not dynamic/expandable data"
			return 0
		fi
		#echo "XATTR: ${_xattr} g:${_group_id} ${mtag}/${VAL}"
		#group_add -c "${mtag}" -g "${VAL}"
		${SQLITE3_CMD} ${formfile} <<EOF
BEGIN TRANSACTION;
DELETE FROM forms WHERE group_id = '${_group_id}';
COMMIT;
EOF
		reload_forms_full
		return 0
	fi

	# errcode from dialog
	local dialog_ok=0

	case "${_type}" in
		inputbox)
			f_dialog_input _input "${_mydesc}" "${VAL}" "${_message}" || return $?
			;;
		password)
			_defaultvalue="${defaultvalue}"
			_mtag="${mtag}"
			if get_password ${_link}; then
				eval ${_mtag}_password="\"${mtag}\""
				_input="*****"
				dialog_ok="1"
			fi
			mtag="${_mtag}"
			defaultvalue="${_defaultvalue}"
			;;
		radio|select)
			_defaultvalue="${defaultvalue}"
			_mtag="${mtag}"
			if get_radio ${_link}; then
				_input="${mtag}"
				dialog_ok="1"
			fi
			mtag="${_mtag}"
			defaultvalue="${_defaultvalue}"
			;;
		checkbox)
			_defaultvalue="${defaultvalue}"
			_mtag="${mtag}"
			if get_checkbox ${_link}; then
				_input="${mtag}"
				dialog_ok="1"
			fi
			mtag="${_mtag}"
			defaultvalue="${_defaultvalue}"
			;;
		group_add)
			# add button
			# echo "${distmoduledir}/forms.d/${module}/initforms.sh"
			#group_add -c "${mtag}" -g "${VAL}"
			group_add -c "${mtag}"
			reload_forms_full
			;;
		group_del)
			# delete button
			# echo "${distmoduledir}/forms.d/${module}/initforms.sh"
			group_del ${_group_id}
			reload_forms_full
			;;
		*)
			;;
	esac

	[ -n "${_input}" -o "${dialog_ok}" = "1" ] && eval ${mtag}="\"${_input}\""
}


export_vars()
{
	local param _id type idx
	local _tmp _res param

	[ ! -f ${formfile} ] && err 1 "${N1_COLOR}formfile not found: ${N2_COLOR}${formfile}${N0_COLOR}"
	[ -z "${table}" ] && table="forms"

	idx=0

	_param="$( cbsdsqlro ${formfile} "SELECT param FROM ${table}" ORDER BY CAST\(order_id AS int\) | ${XARGS_CMD} )"

	helpername=$( cbsdsqlro ${formfile} "SELECT helpername FROM system" )
	# First SQL sequence is 1
	_id=0
	_seq_ind=0
	# H_<env> prefered, we need to pop/push it before/after config env file


	for param in ${_param}; do
		_seq_ind=$(( _seq_ind + 1 ))
		_id="$( cbsdsqlro ${formfile} "SELECT idx FROM ${table} WHERE param=\"${param}\" LIMIT 1" )"
		type="$( cbsdsqlro ${formfile} "SELECT type FROM ${table} WHERE idx=\"${_id}\"" )"
		case "${type}" in
			hiddendelim|subtable|delimer)
				continue
				;;
		esac

		_res="$( cbsdsqlro ${formfile} "SELECT cur FROM ${table} WHERE idx=\"${_id}\"" )"
		[ -z "${_res}" ] && continue

		readconf forms_export_vars.conf
		[ -z "${FORMS_EXPORT_VARS_TPL}" ] && FORMS_EXPORT_VARS_TPL="${jname}_${module}_${param}"

		_tmp=$( echo "${FORMS_EXPORT_VARS_TPL}" | ${TR_CMD} '[:lower:]' '[:upper:]' )
		unset FORMS_EXPORT_VARS_TPL
		echo "${_tmp}=\"${_res}\""
	done
}

show_vars()
{
	local param _id type idx
	local _tmp _res param _all_vars

	[ -z "${formfile}" ] && err 1 "${N1_COLOR}empty formfile:${N0_COLOR}"
	if [ ! -r ${formfile} ]; then
		mksitefile="${distmoduledir}/forms.d/${module}/initforms.sh"
		[ ! -f "${mksitefile}" ] && err 1 "No ${mksitefile}"
		/bin/sh ${mksitefile}
	fi
	[ ! -r ${formfile} ] && err 1 "${N1_COLOR}formfile not found: ${N2_COLOR}${formfile}${N0_COLOR}"
	[ -z "${table}" ] && table="forms"

	idx=0
	_param="$( cbsdsqlro ${formfile} "SELECT param FROM ${table}" ORDER BY CAST\(order_id AS int\) | ${XARGS_CMD} )"

	helpername=$( cbsdsqlro ${formfile} "SELECT helpername FROM system" )
	# First SQL sequence is 1
	_id=0
	_seq_ind=0
	# H_<env> prefered, we need to pop/push it before/after config env file


	for param in ${_param}; do
		_seq_ind=$(( _seq_ind + 1 ))
		_id="$( cbsdsqlro ${formfile} "SELECT idx FROM ${table} WHERE param=\"${param}\" LIMIT 1" )"
		type="$( cbsdsqlro ${formfile} "SELECT type FROM ${table} WHERE idx=\"${_id}\"" )"
		case "${type}" in
			hiddendelim|subtable|delimer)
				continue
				;;
		esac

		_tmp=$( echo "${param}" | ${TR_CMD} '[:lower:]' '[:upper:]' )
		if [ -n "${_all_vars}" ]; then
			_all_vars="${_all_vars} H_${_tmp}"
		else
			_all_vars="H_${_tmp}"
		fi
	done

	echo "${_all_vars}"
}

#### [ MAIN AREA ] ####
# we work in two modes:
# when we got bootstrap file ( which shall contain install_img )
# or only formfile ( can be set in boostrap )
#
# When no bootstrap - load and execute form then exist
# when bootstrap exist - after form execute install_img func
#
# Check for cbsd_puppet_jname jail exist
if [ "${jname}" != "CBSDSYS" ]; then
#	jstatus jname=${cbsd_helper_jname} >/dev/null 2>&1
#	[ $? -ne 1 ] && err 1 "${N1_COLOR}No such ${N2_COLOR}${cbsd_helper_jname}${N1_COLOR} for helper ${N2_COLOR}${helper_module}${N1_COLOR}. Please fetch it via repo command or create from template${N0_COLOR}"
else
	with_bootstrap=1
fi


# Show list modules with no arg
if [ -z "${1}" ]; then
	[ ${header} -eq 1 ] && ${ECHO} "${N1_COLOR}current helper module: ${N2_COLOR}${helper_module}${N0_COLOR}" 1>&2
	[ ! -d ${distmoduledir}/${helper_module}.d ] && exit 0

	[ ${header} -eq 1 ] && ${ECHO} "${BOLD}${UNDERLINE}Installed modules:${N0_COLOR}" 1>&2
	[ ${header} -eq 1 ] && echo 1>&2

	# rename helper_module to forms-<helper>-name!!!
	${FIND_CMD} ${distmoduledir}/forms.d/ -mindepth 1 -maxdepth 1 -type d -exec ${BASENAME_CMD} {} \; | ${SORT_CMD} | while read _dir; do
		p1=${_dir%%_*}
		p2=${_dir##*_}
		echo ${p2}
	done

	[ ${header} -eq 1 ] && ${ECHO} "${N0_COLOR}"
	exit 0
fi

if [ -n "${jname}" ]; then

	case "${jname}" in
		cbsdpuppet1|CBSDSYS)
			with_bootstrap=1
			;;
		*)
			. ${subrdir}/rcconf.subr
			[ $? -eq 1 ] && err 1 "${N1_COLOR}No such jail: ${N2_COLOR}${jname}${N0_COLOR}"
			with_bootstrap=1
			: ${with_bootstrap=1}
			;;
	esac
fi

: ${with_bootstrap=0}

# imghelper_version
# Compare this YYYMM serial with database forms version. When forms have greater number
# this helper is not support this
imghelper_version="201607"
cfg_existing=0

if [ -n "${jname}" -a -n "${module}" ]; then
	formfile="${jailsysdir}/${jname}/helpers/${module}.sqlite"
	if [ ! -r ${formfile} ]; then
		formfile="${workdir}/formfile/${module}.sqlite"
		cfg_existing=0
	else
		cfg_existing=1
		#updcol="cur"
	fi
elif [ -n "${module}" ]; then
	: ${formfile="${workdir}/formfile/${module}.sqlite"}
elif [ -n "${jname}" ]; then
	[ ! -d ${jailsysdir}/${jname}/helpers ] && exit 0
	[ ${header} -eq 1 ] && ${ECHO} "${N1_COLOR}Available modules for ${N2_COLOR}${jname}${N1_COLOR}:${N0_COLOR}"
	[ ${header} -eq 1 ] && ${ECHO} "${BOLD}"

	${FIND_CMD} ${jailsysdir}/${jname}/helpers/ -mindepth 1 -maxdepth 1 -name \*.sqlite -type f -exec ${BASENAME_CMD} {} \; | while read _dir; do
		p1=${_dir%%_*}
		p2=${_dir##*_}
		echo ${p2} | ${SED_CMD} 's/\.sqlite//g'
	done
	[ ${header} -eq 1 ] && ${ECHO} "${N0_COLOR}"
	exit 0
fi

if [ ${show_vars_only} -eq 1 ]; then
	show_vars
	exit 0
fi

# update formfile
if [ ! -d "${workdir}/formfile" ]; then
	# perms for web user via cbsd group
	${MKDIR_CMD} -m 0775 ${workdir}/formfile
	${CHOWN_CMD} cbsd:cbsd ${workdir}/formfile
fi

if [ -n "${module}" ]; then
	[ -f "${distmoduledir}/forms.d/${module}/helpers.conf" ] && . ${distmoduledir}/forms.d/${module}/helpers.conf
	mksitefile="${distmoduledir}/forms.d/${module}/initforms.sh"
	[ ! -f "${mksitefile}" ] && err 1 "No ${mksitefile}"
	/bin/sh ${mksitefile}
fi

[ ! -f "${formfile}" ] && err 1 "Formfile doesn't exist: ${formfile}"

if [ -z "${helper_workdir}" ]; then
	helper_workdir=$( ${DIRNAME_CMD} ${formfile} )
fi

check_version
init_title
reload_forms_full

# in non interactive mode we apply default settings
if [ "${inter}" = "0" ]; then
	x=0
else
	x=1
fi

while [ ${x} -eq 1 ]; do
	dialog_menu_main
	ret=$?
	case ${ret} in
		${DIALOG_OK})
			[ -z "${mtag}" ] && continue
			case "${mtag}" in
				-)
					continue
					;;
				COMMIT)
					tmp=$( all_filled )
					_ret=$?
					if [ ${_ret} -eq 0 ]; then
						x=0
						continue
					else
						f_dialog_msgbox "all field is mandatory: [${tmp}]"
						selected_defaultitem="${tmp}"
					fi
					continue
					;;
				*)
					get_helper_value
					# reread
					#sql_part="${sql_part} ORDER BY order_id"
					#param=$( cbsdsqlro ${formfile} ${sql_part} )
					#load_forms
					#load_new
					;;
			esac
			;;
		${DIALOG_EXTRA})
			get_helper_value "delete"
			continue
			;;
		*)
			exit 0
			;;
	esac
done

# mostly for inter=0 operation (e.g. webdev/clonos/other frontend)
# before with_bootstrap exit
case "${group}" in
	add)
		groupname="${ogroupname}"
		[ -z "${groupname}" ] && err 1 "${N1_COLOR}empty groupname= for group=add${N0_COLOR}"
		group_add -c "${groupname}"
		;;
	del)
		group_del
		;;
	*)
		;;
esac

# export global variable to new module (when init)
#if [ -r "${distmoduledir}/puppet.d/sync_env2form" ]; then
#	sync_env2form
#fi

# no bootrstap? this is the end my beautiful friend
[ ${with_bootstrap} -eq 0 ] && exit 0

[ -n "${oupdcol}" ] && updcol="${oupdcol}"
update_params ${updcol}

# commit when works with module
if [ -n "$helper_module}" ]; then
	case "${jname}" in
		CBSDSYS)
			echo "HERE ${formfile}, debug: ${debug_form}"
			if [ -r ${distmoduledir}/forms.d/${module}/cbsdsys ]; then
				${distmoduledir}/forms.d/${module}/cbsdsys ${formfile}
			else
				${helper_module} jname=${jname} module=${module} mode=apply debug_form=${debug_form}
			fi
			;;
		cbsdpuppet1)
			[ -z "${out}" ] && out="/dev/stdout"
			${helper_module} jname=${jname} module=${module} mode=manifest > ${out}
			;;
		*)
			case "${helper_module}" in
				cbsdsys)
					${distmoduledir}/forms.d/${module}/cbsdsys ${formfile} ${jname}
					;;
				*)
					echo "${helper_module} jname=${jname} module=${module} mode=apply debug_form=${debug_form}"
					${helper_module} jname=${jname} module=${module} mode=apply debug_form=${debug_form}
					# re-export global variable
#					if [ -r "${distmoduledir}/puppet.d/sync_env2form" ]; then
#						sync_env2form
#					fi

					[ -n "${oexport}" ] && export="${oexport}"
					[ -n "${export}" ] && export_vars

					# Looking for helpers pre/post hooks (todo: also lookup in $moduledir)
					if [ -d "${distmoduledir}/forms.d/${module}/jail-system-default" ]; then
						cd ${distmoduledir}/forms.d/${module}/jail-system-default
						for i in $( ${FIND_CMD} . -mindepth 2 -maxdepth 2 -type f ); do
							jp=$( echo ${i} | ${SED_CMD} s:^./:${jailsysdir}/${jname}\/:g )
							if [ ! -r ${jp} ]; then
								${ECHO} "${N1_COLOR}Install helpers hook: ${N2_COLOR}${jp}${N0_COLOR}"
								${CP_CMD} -a ${i} ${jp}
							fi
						done
					fi

					;;
			esac
			;;
	esac
fi

exit 0
