#!/bin/sh
# SecuBox Backup Manager RPCD Handler

. /usr/share/libubox/jshn.sh

BACKUP_CMD="/usr/sbin/secubox-backup"

case "$1" in
	list)
		cat <<-EOF
		{
			"status": {},
			"list": { "type": "string" },
			"container_list": {},
			"create": { "type": "string" },
			"restore": { "file": "string", "dry_run": "boolean" },
			"cleanup": {},
			"container_backup": { "name": "string" },
			"container_restore": { "name": "string", "file": "string" }
		}
		EOF
		;;

	call)
		case "$2" in
			status)
				json_init

				# Get storage info
				storage=$($BACKUP_CMD status 2>/dev/null | grep "Storage Path" | cut -d: -f2 | tr -d ' ')
				used=$($BACKUP_CMD status 2>/dev/null | grep "Storage Used" | cut -d: -f2 | tr -d ' ')

				json_add_string "storage_path" "${storage:-/srv/backups}"
				json_add_string "storage_used" "${used:-0}"

				# Last backup times
				json_add_object "last_backup"
				for type in config containers services; do
					latest=$(ls -t "${storage:-/srv/backups}/$type/"*.tar* 2>/dev/null | head -1)
					if [ -n "$latest" ]; then
						bdate=$(stat -c %Y "$latest" 2>/dev/null)
						json_add_int "$type" "${bdate:-0}"
					else
						json_add_int "$type" 0
					fi
				done
				json_close_object

				# Container count
				containers=$(ls -d /srv/lxc/*/ 2>/dev/null | wc -l)
				json_add_int "container_count" "$containers"

				json_dump
				;;

			list)
				json_load "$3"
				json_get_var type type
				type="${type:-all}"

				storage=$(uci -q get backup.main.storage_path)
				storage="${storage:-/srv/backups}"

				json_init
				json_add_array "backups"

				# List config backups
				if [ "$type" = "all" ] || [ "$type" = "config" ]; then
					ls "$storage/config/"*.tar* 2>/dev/null | while read f; do
						[ -f "$f" ] || continue
						json_add_object ""
						json_add_string "file" "$(basename "$f")"
						json_add_string "type" "config"
						json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
						json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
						json_close_object
					done
				fi

				# List container backups
				if [ "$type" = "all" ] || [ "$type" = "containers" ]; then
					ls "$storage/containers/"*.tar* 2>/dev/null | while read f; do
						[ -f "$f" ] || continue
						json_add_object ""
						json_add_string "file" "$(basename "$f")"
						json_add_string "type" "container"
						json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
						json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
						json_close_object
					done
				fi

				# List service backups
				if [ "$type" = "all" ] || [ "$type" = "services" ]; then
					ls "$storage/services/"*.tar* 2>/dev/null | while read f; do
						[ -f "$f" ] || continue
						json_add_object ""
						json_add_string "file" "$(basename "$f")"
						json_add_string "type" "service"
						json_add_string "size" "$(du -h "$f" 2>/dev/null | cut -f1)"
						json_add_int "timestamp" "$(stat -c %Y "$f" 2>/dev/null)"
						json_close_object
					done
				fi

				json_close_array
				json_dump
				;;

			container_list)
				json_init
				json_add_array "containers"

				for dir in /srv/lxc/*/; do
					[ -d "$dir" ] || continue
					name=$(basename "$dir")
					[ -f "$dir/config" ] || continue

					state="stopped"
					lxc-info -n "$name" 2>/dev/null | grep -q "RUNNING" && state="running"
					size=$(du -sh "$dir" 2>/dev/null | awk '{print $1}')

					# Count backups for this container
					storage=$(uci -q get backup.main.storage_path)
					storage="${storage:-/srv/backups}"
					backup_count=$(ls -1 "$storage/containers/${name}-"*.tar* 2>/dev/null | wc -l)

					json_add_object ""
					json_add_string "name" "$name"
					json_add_string "state" "$state"
					json_add_string "size" "$size"
					json_add_int "backups" "$backup_count"
					json_close_object
				done

				json_close_array
				json_dump
				;;

			create)
				json_load "$3"
				json_get_var type type
				type="${type:-full}"

				result=$($BACKUP_CMD create --$type 2>&1)
				rc=$?

				json_init
				json_add_int "code" "$rc"
				json_add_string "output" "$result"
				json_dump
				;;

			restore)
				json_load "$3"
				json_get_var file file
				json_get_var dry_run dry_run

				[ -z "$file" ] && {
					json_init
					json_add_int "code" 1
					json_add_string "error" "No file specified"
					json_dump
					exit 0
				}

				opts=""
				[ "$dry_run" = "1" ] || [ "$dry_run" = "true" ] && opts="--dry-run"

				result=$($BACKUP_CMD restore "$file" $opts 2>&1)
				rc=$?

				json_init
				json_add_int "code" "$rc"
				json_add_string "output" "$result"
				json_dump
				;;

			cleanup)
				result=$($BACKUP_CMD cleanup 2>&1)
				rc=$?

				json_init
				json_add_int "code" "$rc"
				json_add_string "output" "$result"
				json_dump
				;;

			container_backup)
				json_load "$3"
				json_get_var name name

				[ -z "$name" ] && {
					json_init
					json_add_int "code" 1
					json_add_string "error" "No container name specified"
					json_dump
					exit 0
				}

				result=$($BACKUP_CMD container backup "$name" 2>&1)
				rc=$?

				json_init
				json_add_int "code" "$rc"
				json_add_string "output" "$result"
				json_dump
				;;

			container_restore)
				json_load "$3"
				json_get_var name name
				json_get_var file file

				[ -z "$name" ] || [ -z "$file" ] && {
					json_init
					json_add_int "code" 1
					json_add_string "error" "Container name and backup file required"
					json_dump
					exit 0
				}

				result=$($BACKUP_CMD container restore "$name" "$file" 2>&1)
				rc=$?

				json_init
				json_add_int "code" "$rc"
				json_add_string "output" "$result"
				json_dump
				;;
		esac
		;;
esac

exit 0
