#!/bin/sh

po_domain="alterator-bacula"
alterator_api_version=1
bacula_general_config_file="/etc/alterator/bacula/general"

### defaults
default_system_backup_path="$(readlink -e /srv)"
default_disk_retention=7

. bacula-alterator-sh-functions
. bacula-client-sh-functions
. bacula-local-sh-functions

. shell-config

### configs

config_get()
{
    local v="$(shell_config_get "$bacula_general_config_file" "$1")"
    echo "${v:-$2}"
}

config_set()
{
    shell_config_set "$bacula_general_config_file" "$1" "$2"
}

### local disk related functions

info_disk()
{
    local device="$1";shift
    local parent_device="$(partition_parent "$device")"
    local size=

    if [ -z "$parent_device" ] ;then
	parent_device="$device"
	size="$(disk_size "$device")"
    else
	size="$(partition_size "$device")"
    fi


    printf '%s (%s %s)\n' \
	"$device" \
	"$(job_size "$size")" \
	"$(disk_info "$parent_device")"
}

list_disk()
{
    local uuid device filesystem mpoint

    bacula_device_list|
	while read uuid device filesystem mpoint; do
	    [ -z "$mpoint" ] ||
		[ "$mpoint" != "/" -a -n "${default_system_backup_path##$mpoint*}" ] ||
		continue
	    write_enum_item "$uuid" "$(info_disk "$device")"
	done
}

del_disk()
{
    local old_path="$(bacula_local_storage_get_path)"
    local type="$(config_get disk)"
    local do_mount="$(config_get disk_mount)"

    # purge volume data
    bacula_local_backup_clear "$old_path"

    # we are using lazy umount variant
    if [ "$type" = "user"  -a "$do_mount" = "1" -a -n "$old_path" ];then
	echo "umounting..." >&2
	umount -l -- "$old_path" >&2
	fstab_del "$old_path"
    fi
}

add_disk()
{
    local uuid="$1";shift

    # create new mount point
    bacula_device_list|
	grep -m1 "^$(quote_sed_regexp "$uuid")[[:space:]]"|
	(read uuid device filesystem mpoint;

	    [ -n "$device" ] || return 0

	    config_set disk_device "$device"

	    if [ -n "$mpoint" ];then
		config_set disk_mount 0
		echo "$mpoint"
	    else
		config_set disk_mount 1
		mpoint="$bacula_mount_dir"
		[ "$filesystem" != "ntfs" ] || filesystem="ntfs-3g"

		mkdir -p -- "$mpoint"
		fstab_add "UUID=$uuid" "$mpoint" "$filesystem defaults 0 0"
		mount -- "$mpoint" >&2 && echo "$mpoint"
	    fi)
}

name_disk()
{
    local v="$(config_get disk "none")"

    case "$v" in
        system) printf '%s (%s)' "`_ "System disk"`" "$default_system_backup_path" ;;
        user) info_disk "$(config_get disk_device)" ;;
        *)  echo " - " ;;
    esac
}

list_retention()
{
    write_enum_item 7  "`_ "1 week"`"
    write_enum_item 14 "`_ "2 weeks"`"
    write_enum_item 30  "`_ "1 month"`"
}

init_disk()
{
    grep -wqs "$bacula_magic_string" "$bacula_device_file" && return 0

    config_set disk "system"

    bacula_local_pool_set_retention "$default_disk_retention"
    bacula_local_storage_set_path "$default_system_backup_path"

    bacula_local_backup_clear "$default_system_backup_path"
}

### initial actions
init_disk

on_message()
{
  case "$in_action" in
    type)
	write_type_item time time
	write_type_item restore_date date
	;;
    read)
	case "$in__objects" in
	    /)
		# data from config
		write_string_param mode "$(config_get mode "off")"
		write_string_param disk_name "$(name_disk)"
		write_string_param disk "$(config_get disk "none")"

		#defaults
		write_string_param restore_date "$(date +%F)"
		write_string_param restore_type "file"

		# data directly from bacula
		local latest_backup_time="$(bacula_local_backup_date_list|head -n1)"
		local oldest_backup_time="$(bacula_local_backup_date_list|tail -n1)"
		write_string_param latest_backup_time "${latest_backup_time:- - }"
		write_string_param oldest_backup_time "${oldest_backup_time:- - }"
		write_string_param time "$(bacula_local_get_time)"
		;;
	    disk)
		write_string_param system_disk_path "$default_system_backup_path"
		write_string_param disk "$(config_get disk "system")"
		write_string_param disk_uuid "$(config_get disk_uuid)"
		write_string_param retention "$(bacula_local_pool_get_retention)"
		;;
	esac
	;;
    write)
	case "$in__objects" in
	    /)
		if [ -z "$(config_get disk "")" ];then
		    write_error "`_ "Please choose backup disk"`"
		    return
		fi

		[ -z "$in_mode" ] ||
		    case "$in_mode" in
			daily)
			    if [  -z "$in_time" ];then
				write_error "`_ "Please define backup start time"`"
				return
			    else
				config_set mode "$in_mode"

				bacula_local_set_time "$in_time"
				bacula_daemon_on
			    fi
			    ;;
			off)
			    config_set mode "$in_mode"
			    bacula_daemon_off
			    ;;
		    esac
		;;
	    disk)
		daemon_ready || return

		del_disk
		local new_path=
		case "$in_disk" in
		    system)
			new_path="$default_system_backup_path"
			;;
		    user)
			if [ -z "$in_disk_uuid" ];then
			    write_error "`_ "Disk is not selected"`"
			    return
			fi
			local new_path="$(add_disk "$in_disk_uuid")"
			if [ -z "$new_path" ];then
			    write_error "`_ "Unable to mount disk"`"
			    return
			fi
			config_set disk_uuid "$in_disk_uuid"
			;;
		esac

		config_set disk "$in_disk"
		[ -z "$in_retention" ] || bacula_local_pool_set_retention "$in_retention"
		bacula_local_storage_set_path "$new_path"

		daemon_restart_all
		;;
	esac
	;;
    cancelbackup)
	bacula_local_backup_cancel
	;;
    backup)
	bacula_local_backup_run
	;;
    exclude_add)
	[ -n "$in_new_exclude" ] || return
	bacula_local_exclude_add "$in_new_exclude"
	;;
    exclude_del)
	[ -n "$in_exclude" ] || return
	bacula_local_exclude_del "$in_exclude"
	;;
    status)
	[ -n "$in_jobid" ] || return
	write_string_param job_status "$(bacula_job_status "$in_jobid")"
	write_string_param job_progress "$(bacula_local_client_status)"
	;;
    restore)
	[ -n "$in_restore_date" -a -n "$in_restore_path" ] || return

	local jobid="$(bacula_local_restore_file "$in_restore_date" "$in_restore_path")"
	if [ -z "$jobid" ];then
	    write_error "`_ "Unable to restore"`"
	    return
	fi

	write_string_param jobid "$jobid"
	;;
    list)
	case "$in__objects" in
	    jobs)
		local date status
		bacula_local_waiting_list|
		    while read date; do
			write_table_item \
			    creation_date "$date" \
			    creation_result "$(job_status C)" \
			    creation_class "$(job_class C)"
		    done
		bacula_local_backup_list|
		    while IFS='	' read date status; do
			write_table_item \
			    creation_date "$date" \
			    creation_result "$(job_status "$status")" \
			    creation_class "$(job_class "$status")"
		    done
		;;
	    exclude)
		local f
		bacula_local_exclude_list|
		    while read f;do
			write_enum_item "$f"
		    done
		;;
	    retention) list_retention;;
	    disk) list_disk;;
	esac
	;;
  esac
}

message_loop
