package PVE::API2::Storage::PruneBackups;

use strict;
use warnings;

use PVE::Cluster;
use PVE::JSONSchema qw(get_standard_option);
use PVE::RESTHandler;
use PVE::RPCEnvironment;
use PVE::Storage;
use PVE::Tools qw(extract_param);

use base qw(PVE::RESTHandler);

__PACKAGE__->register_method ({
    name => 'dryrun',
    path => '',
    method => 'GET',
    description => "Get prune information for backups. NOTE: this is only a preview and might not be " .
		   "what a subsequent prune call does if backups are removed/added in the meantime.",
    permissions => {
	check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
    },
    protected => 1,
    proxyto => 'node',
    parameters => {
	additionalProperties => 0,
	properties => {
	    node => get_standard_option('pve-node'),
	    storage => get_standard_option('pve-storage-id', {
		completion => \&PVE::Storage::complete_storage_enabled,
            }),
	    'prune-backups' => get_standard_option('prune-backups', {
		description => "Use these retention options instead of those from the storage configuration.",
		optional => 1,
	    }),
	    type => {
		description => "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.",
		type => 'string',
		optional => 1,
		enum => ['qemu', 'lxc'],
	    },
	    vmid => get_standard_option('pve-vmid', {
		description => "Only consider backups for this guest.",
		optional => 1,
		completion => \&PVE::Cluster::complete_vmid,
	    }),
	},
    },
    returns => {
	type => 'array',
	items => {
	    type => 'object',
	    properties => {
		volid => {
		    description => "Backup volume ID.",
		    type => 'string',
		},
		'ctime' => {
		    description => "Creation time of the backup (seconds since the UNIX epoch).",
		    type => 'integer',
		},
		'mark' => {
		    description => "Whether the backup would be kept or removed. Backups that are" .
			" protected or don't use the standard naming scheme are not removed.",
		    type => 'string',
		    enum => ['keep', 'remove', 'protected', 'renamed'],
		},
		type => {
		    description => "One of 'qemu', 'lxc', 'openvz' or 'unknown'.",
		    type => 'string',
		},
		'vmid' => {
		    description => "The VM the backup belongs to.",
		    type => 'integer',
		    optional => 1,
		},
	    },
	},
    },
    code => sub {
	my ($param) = @_;

	my $cfg = PVE::Storage::config();

	my $vmid = extract_param($param, 'vmid');
	my $type = extract_param($param, 'type');
	my $storeid = extract_param($param, 'storage');

	my $prune_backups = extract_param($param, 'prune-backups');
	$prune_backups = PVE::JSONSchema::parse_property_string('prune-backups', $prune_backups)
	    if defined($prune_backups);

	return PVE::Storage::prune_backups($cfg, $storeid, $prune_backups, $vmid, $type, 1);
    }});

__PACKAGE__->register_method ({
    name => 'delete',
    path => '',
    method => 'DELETE',
    description => "Prune backups. Only those using the standard naming scheme are considered.",
    permissions => {
	description => "You need the 'Datastore.Allocate' privilege on the storage " .
		       "(or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).",
	user => 'all',
    },
    protected => 1,
    proxyto => 'node',
    parameters => {
	additionalProperties => 0,
	properties => {
	    node => get_standard_option('pve-node'),
	    storage => get_standard_option('pve-storage-id', {
                completion => \&PVE::Storage::complete_storage,
            }),
	    'prune-backups' => get_standard_option('prune-backups', {
		description => "Use these retention options instead of those from the storage configuration.",
	    }),
	    type => {
		description => "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.",
		type => 'string',
		optional => 1,
		enum => ['qemu', 'lxc'],
	    },
	    vmid => get_standard_option('pve-vmid', {
		description => "Only prune backups for this VM.",
		completion => \&PVE::Cluster::complete_vmid,
		optional => 1,
	    }),
	},
    },
    returns => { type => 'string' },
    code => sub {
	my ($param) = @_;

	my $rpcenv = PVE::RPCEnvironment::get();
	my $authuser = $rpcenv->get_user();

	my $cfg = PVE::Storage::config();

	my $vmid = extract_param($param, 'vmid');
	my $type = extract_param($param, 'type');
	my $storeid = extract_param($param, 'storage');

	my $prune_backups = extract_param($param, 'prune-backups');
	$prune_backups = PVE::JSONSchema::parse_property_string('prune-backups', $prune_backups)
	    if defined($prune_backups);

	if (defined($vmid)) {
	    $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
	    $rpcenv->check($authuser, "/vms/$vmid", ['VM.Backup']);
	} else {
	    $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.Allocate']);
	}

	my $id = (defined($vmid) ? "$vmid@" : '') . $storeid;
	my $worker = sub {
	    PVE::Storage::prune_backups($cfg, $storeid, $prune_backups, $vmid, $type, 0);
	};

	return $rpcenv->fork_worker('prunebackups', $id, $authuser, $worker);
    }});

1;
