#!/bin/sh

po_domain="alterator-bacula"
alterator_api_version=1
cache_dir=/var/cache/alterator/bacula-client-backup
storage_dir=/srv

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

### cache

reset_cache()
{
  rm -rf -- "$cache_dir"
  mkdir -p -- "$cache_dir"
}

### filelist
__filelist_check()
{
    [ -f "$1" ] ||
	cp -f -- "$(bacula_client_filelist_path "$2" "$3")" "$1"
}

client_filelist_list()
{
    local name="$1";shift
    local type="$1";shift
    local file="$cache_dir/filelist-$type-$name"
    __filelist_check "$file" "$name" "$type"
    cat "$file"
}

client_filelist_add()
{
    local name="$1";shift
    local type="$1";shift
    local path="$1";shift
    local file="$cache_dir/filelist-$type-$name"
    __filelist_check "$file" "$name" "$type"

    file_list_add "$file" "$path"
}

client_filelist_del()
{
    local name="$1";shift
    local type="$1";shift
    local path="$1";shift
    local file="$cache_dir/filelist-$type-$name"
    __filelist_check "$file" "$name" "$type"

    file_list_del "$file" "$path"
}

client_filelist_commit()
{
    local name="$1";shift
    local type="$1";shift
    local file="$cache_dir/filelist-$type-$name"

    mv -f -- "$file" "$(bacula_client_filelist_path "$name" "$type")"
}

client_filelist_reset()
{
    local name="$1";shift
    local type="$1";shift
    local file="$cache_dir/filelist-$type-$name"

    rm -f -- "$file"
}

### initial actions

reset_cache

on_message()
{
  case "$in_action" in
    type)
	write_type_item address		hostname
	write_type_item port		tcp-port
	write_type_item new_name	system-computer-name
	write_type_item password	bacula-password
	write_type_item schedule_time	time
	write_type_item restore_date	date
	;;
    read)
	case "$in__objects" in
	    /)
		[ -n "$in_name" ] || return

		write_string_param address "$(bacula_client_get_address "$in_name")"
		write_string_param port "$(bacula_client_get_port "$in_name")"

		write_string_param schedule_status "$(bacula_client_get_schedule "$in_name")"
		write_string_param schedule_time "$(bacula_client_get_time "$in_name")"
		;;
	    archive)
		[ -n "$in_name" ] || return
		write_string_param restore_date "$(date +%F)"
		write_string_param retention "$(bacula_client_get_retention "$in_name")"
		;;
	esac
	;;
    write)
	case "$in__objects" in
	    /)
		[ -n "$in_name" ] || return
		[ -z "$in_schedule_status" ] || bacula_client_set_schedule "$in_name" "$in_schedule_status"
		[ -z "$in_schedule_time" ] || bacula_client_set_time "$in_name" "$in_schedule_time"
		[ -z "$in_address" ] || bacula_client_set_address "$in_name" "$in_address"
		[ -z "$in_port" ] || bacula_client_set_port "$in_name" "$in_port"
		[ -z "$in_password" ] || bacula_client_set_password "$in_name" "$in_password"
		;;
	    archive)
		[ -n "$in_name" ] || return
		[ -z "$in_retention" ] || bacula_client_set_retention "$in_name" "$in_retention"
		;;
	esac
	/sbin/service bacula-dir condreload >&2
	;;
    list)
	case "$in__objects" in
	    client)
		bacula_client_list|write_enum
		;;
	    retention)
		write_enum_item 7  "`_ "1 week"`"
		write_enum_item 14 "`_ "2 weeks"`"
		write_enum_item 30  "`_ "1 month"`"
		;;
	    template)
		bacula_client_template_list "$in_language"|write_enum
		;;
	    schedule)
		local tempfile="$(mktemp -t bacula-backup.XXXXXX)"
		bacula_client_schedule_list >"$tempfile"
		local hour time client
		for hour in `seq 0 23`;do
		    hour="$(printf '%02d' "$hour")"
		    printf '%s:00\t%s\n' "$hour" "$(sed -n "s/^$hour:[0-9]\+:[0-9]\+[[:space:]]\+//p" "$tempfile"|tr '\n' ' ')"
		done|
		    while read time client;do
			[ -z "$client" ] ||
			    write_table_item full_schedule_time "$time" full_schedule_client "$client"
		    done
		rm -f -- "$tempfile"
		;;
	    backup)
		local client first_date last_date last_status bytes data;
		bacula_client_list|
		    while read client; do
			if [ "$(bacula_client_backup_count "$client")" = "0" ];then
			    first_date='-'
			    last_date='-'
			    bytes='0'
			else
			    data="$(bacula_client_backup_summary "$client")"
			    first_date="$(echo "$data"|cut -f1 -d'	')"
			    last_date="$(echo "$data"|cut -f2 -d'	')"
			    bytes="$(echo "$data"|cut -f3 -d'	')"
			fi
			#human readable values
			last_status="$(bacula_client_backup_last_status "$client")"
			local last_status_string="$(job_status "$last_status")"
			local last_status_class="$(job_class "$last_status")"
			bytes="$(job_size "$bytes")"
			write_table_item \
			    client_name "$client" \
			    client_first_date "$first_date" \
			    client_last_date "$last_date" \
			    client_last_status_string "$last_status_string" \
			    client_last_status_class "$last_status_class" \
			    client_bytes "$bytes"
		    done
		;;
	esac
	;;
    filelist_commit)
	[ -n "$in_name" -a -n "$in_type" ] || return
	client_filelist_commit "$in_name" "$in_type"
	;;
    filelist_reset)
	[ -n "$in_name" -a -n "$in_type" ] || return
	client_filelist_reset "$in_name" "$in_type"
	;;
    filelist_list)
	[ -n "$in_name" -a -n "$in_type" ] || return
	local IFS='' #read all as a single word
	client_filelist_list "$in_name" "$in_type"|write_enum
	;;
    filelist_add)
	[ -n "$in_new_path" -a -n "$in_name" -a -n "$in_type" ] || return
	client_filelist_add "$in_name" "$in_type" "$in_new_path"
	;;
    filelist_del)
	[ -n "$in_path" -a -n "$in_name" -a -n "$in_type" ] || return
	local IFS=';'
	for i in $in_path; do
	    client_filelist_del "$in_name" "$in_type" "$i"
	done
	;;
    client_add)
	[ -n "$in_new_name" ] || return

	if bacula_client_exists "$in_new_name";then
	    write_error "`_ "Same client already exists"`"
	    return
	fi

	bacula_client_add "$in_new_name" "$in_template"
	/sbin/service bacula-dir condreload >&2
	;;
    client_del)
	[ -n "$in_name" ] || return

	bacula_client_del "$in_name" "$storage_dir"
	/sbin/service bacula-dir condreload >&2
	;;
    client_clear)
	[ -n "$in_name" ] || return
	bacula_client_clear "$in_name" "$storage_dir"
	;;
    client_backup)
	[ -n "$in_name" ] || return
	bacula_client_backup_run "$in_name"
	;;
    client_status)
	[ -n "$in_name" -a -n "$in_jobid" ] || return
	write_string_param job_status "$(bacula_job_status "$in_jobid")"
	write_string_param job_progress "$(bacula_client_get_progress "$in_name")"
	;;
    client_restore)
	[ -n "$in_name" -a -n "$in_restore_date" -a -n "$in_restore_path" ] || return

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

	write_string_param jobid "$jobid"
	;;
    client_config)
	[ -n "$in_name" ] || return

	bacula_client_template_fd "$in_name"|write_blob_param config
  esac
}

message_loop
