Ext.define('PVE.window.Restore', {
    extend: 'Ext.window.Window', // fixme: Proxmox.window.Edit?

    resizable: false,
    width: 500,
    modal: true,
    layout: 'auto',
    border: false,

    controller: {
	xclass: 'Ext.app.ViewController',
	control: {
	    '#liveRestore': {
		change: function(el, newVal) {
		    let liveWarning = this.lookupReference('liveWarning');
		    liveWarning.setHidden(!newVal);
		    let start = this.lookupReference('start');
		    start.setDisabled(newVal);
		},
	    },
	    'form': {
		validitychange: function(f, valid) {
		    this.lookupReference('doRestoreBtn').setDisabled(!valid);
		},
	    },
	},

	doRestore: function() {
	    let me = this;
	    let view = me.getView();

	    let values = view.down('form').getForm().getValues();

	    let params = {
		vmid: view.vmid || values.vmid,
		force: view.vmid ? 1 : 0,
	    };
	    if (values.unique) {
		params.unique = 1;
	    }
	    if (values.start && !values['live-restore']) {
		params.start = 1;
	    }
	    if (values['live-restore']) {
		params['live-restore'] = 1;
	    }
	    if (values.storage) {
		params.storage = values.storage;
	    }

	    ['bwlimit', 'cores', 'name', 'memory', 'sockets'].forEach(opt => {
		if ((values[opt] ?? '') !== '') {
		    params[opt] = values[opt];
		}
	    });

	    if (params.name && view.vmtype === 'lxc') {
		params.hostname = params.name;
		delete params.name;
	    }

	    let confirmMsg;
	    if (view.vmtype === 'lxc') {
		params.ostemplate = view.volid;
		params.restore = 1;
		if (values.unprivileged !== 'keep') {
		    params.unprivileged = values.unprivileged;
		}
		confirmMsg = Proxmox.Utils.format_task_description('vzrestore', params.vmid);
	    } else if (view.vmtype === 'qemu') {
		params.archive = view.volid;
		confirmMsg = Proxmox.Utils.format_task_description('qmrestore', params.vmid);
	    } else {
		throw 'unknown VM type';
	    }

	    let executeRestore = () => {
		Proxmox.Utils.API2Request({
		    url: `/nodes/${view.nodename}/${view.vmtype}`,
		    params: params,
		    method: 'POST',
		    waitMsgTarget: view,
		    failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus),
		    success: function(response, options) {
			Ext.create('Proxmox.window.TaskViewer', {
			    autoShow: true,
			    upid: response.result.data,
			});
			view.close();
		    },
		});
	    };

	    if (view.vmid) {
		confirmMsg += `. ${Ext.String.format(
		    gettext('This will permanently erase current {0} data.'),
		    view.vmtype === 'lxc' ? 'CT' : 'VM',
		)}`;
		if (view.vmtype === 'lxc') {
		    confirmMsg += `<br>${gettext('Mount point volumes are also erased.')}`;
		}
		Ext.Msg.confirm(gettext('Confirm'), confirmMsg, function(btn) {
		    if (btn === 'yes') {
			executeRestore();
		    }
		});
	    } else {
		executeRestore();
	    }
	},

	afterRender: function() {
	    let view = this.getView();

	    Proxmox.Utils.API2Request({
		url: `/nodes/${view.nodename}/vzdump/extractconfig`,
		method: 'GET',
		waitMsgTarget: view,
		params: {
		    volume: view.volid,
		},
		failure: response => Ext.Msg.alert('Error', response.htmlStatus),
		success: function(response, options) {
		    let allStoragesAvailable = true;

		    response.result.data.split('\n').forEach(line => {
			let [_, key, value] = line.match(/^([^:]+):\s*(\S+)\s*$/) ?? [];

			if (!key) {
			    return;
			}

			if (key === '#qmdump#map') {
			    let match = value.match(/^(\S+):(\S+):(\S*):(\S*):$/) ?? [];
			    // if a /dev/XYZ disk was backed up, there is no storage hint
			    allStoragesAvailable &&= !!match[3] && !!PVE.data.ResourceStore.getById(
				`storage/${view.nodename}/${match[3]}`);
			} else if (key === 'name' || key === 'hostname') {
			    view.lookupReference('nameField').setEmptyText(value);
			} else if (key === 'memory' || key === 'cores' || key === 'sockets') {
			    view.lookupReference(`${key}Field`).setEmptyText(value);
			}
		    });

		    if (!allStoragesAvailable) {
			let storagesel = view.down('pveStorageSelector[name=storage]');
			storagesel.allowBlank = false;
			storagesel.setEmptyText('');
		    }
		},
	    });
	},
    },

    initComponent: function() {
	let me = this;

	if (!me.nodename) {
	    throw "no node name specified";
	}
	if (!me.volid) {
	    throw "no volume ID specified";
	}
	if (!me.vmtype) {
	    throw "no vmtype specified";
	}

	let storagesel = Ext.create('PVE.form.StorageSelector', {
	    nodename: me.nodename,
	    name: 'storage',
	    value: '',
	    fieldLabel: gettext('Storage'),
	    storageContent: me.vmtype === 'lxc' ? 'rootdir' : 'images',
	    // when restoring a container without specifying a storage, the backend defaults
	    // to 'local', which is unintuitive and 'rootdir' might not even be allowed on it
	    allowBlank: me.vmtype !== 'lxc',
	    emptyText: me.vmtype === 'lxc' ? '' : gettext('From backup configuration'),
	    autoSelect: me.vmtype === 'lxc',
	});

	let items = [
	    {
		xtype: 'displayfield',
		value: me.volidText || me.volid,
		fieldLabel: gettext('Source'),
	    },
	    storagesel,
	    {
		xtype: 'pmxDisplayEditField',
		name: 'vmid',
		fieldLabel: me.vmtype === 'lxc' ? 'CT' : 'VM',
		value: me.vmid,
		editable: !me.vmid,
		editConfig: {
		    xtype: 'pveGuestIDSelector',
		    guestType: me.vmtype,
		    loadNextFreeID: true,
		    validateExists: false,
		},
	    },
	    {
		xtype: 'pveBandwidthField',
		name: 'bwlimit',
		backendUnit: 'KiB',
		allowZero: true,
		fieldLabel: gettext('Bandwidth Limit'),
		emptyText: gettext('Defaults to target storage restore limit'),
		autoEl: {
		    tag: 'div',
		    'data-qtip': gettext("Use '0' to disable all bandwidth limits."),
		},
	    },
	    {
		xtype: 'fieldcontainer',
		layout: 'hbox',
		items: [{
		    xtype: 'proxmoxcheckbox',
		    name: 'unique',
		    fieldLabel: gettext('Unique'),
		    flex: 1,
		    autoEl: {
			tag: 'div',
			'data-qtip': gettext('Autogenerate unique properties, e.g., MAC addresses'),
		    },
		    checked: false,
		},
		{
		    xtype: 'proxmoxcheckbox',
		    name: 'start',
		    reference: 'start',
		    flex: 1,
		    fieldLabel: gettext('Start after restore'),
		    labelWidth: 105,
		    checked: false,
		}],
	    },
	];

	if (me.vmtype === 'lxc') {
	    items.push(
		{
		    xtype: 'radiogroup',
		    fieldLabel: gettext('Privilege Level'),
		    reference: 'noVNCScalingGroup',
		    height: '15px', // renders faster with value assigned
		    layout: {
			type: 'hbox',
			algin: 'stretch',
		    },
		    autoEl: {
			tag: 'div',
			'data-qtip':
			    gettext('Choose if you want to keep or override the privilege level of the restored Container.'),
		    },
		    items: [
			{
			    xtype: 'radiofield',
			    name: 'unprivileged',
			    inputValue: 'keep',
			    boxLabel: gettext('From Backup'),
			    flex: 1,
			    checked: true,
			},
			{
			    xtype: 'radiofield',
			    name: 'unprivileged',
			    inputValue: '1',
			    boxLabel: gettext('Unprivileged'),
			    flex: 1,
			},
			{
			    xtype: 'radiofield',
			    name: 'unprivileged',
			    inputValue: '0',
			    boxLabel: gettext('Privileged'),
			    flex: 1,
			    //margin: '0 0 0 10',
			},
		    ],
		},
	    );
	} else if (me.vmtype === 'qemu') {
	    items.push({
		xtype: 'proxmoxcheckbox',
		name: 'live-restore',
		itemId: 'liveRestore',
		flex: 1,
		fieldLabel: gettext('Live restore'),
		checked: false,
		hidden: !me.isPBS,
	    },
	    {
		xtype: 'displayfield',
		reference: 'liveWarning',
		// TODO: Remove once more tested/stable?
		value: gettext('Note: If anything goes wrong during the live-restore, new data written by the VM may be lost.'),
		userCls: 'pmx-hint',
		hidden: true,
	    });
	}

	items.push({
	    xtype: 'fieldset',
	    title: `${gettext('Override Settings')}:`,
	    layout: 'hbox',
	    defaults: {
		border: false,
		layout: 'anchor',
		flex: 1,
	    },
	    items: [
		{
		    padding: '0 10 0 0',
		    items: [{
			xtype: 'textfield',
			fieldLabel: me.vmtype === 'lxc' ? gettext('Hostname') : gettext('Name'),
			name: 'name',
			vtype: 'DnsName',
			reference: 'nameField',
			allowBlank: true,
		    }, {
			xtype: 'proxmoxintegerfield',
			fieldLabel: gettext('Cores'),
			name: 'cores',
			reference: 'coresField',
			minValue: 1,
			maxValue: 128,
			allowBlank: true,
		    }],
		},
		{
		    padding: '0 0 0 10',
		    items: [
		    {
			xtype: 'pveMemoryField',
			fieldLabel: gettext('Memory'),
			name: 'memory',
			reference: 'memoryField',
			value: '',
			allowBlank: true,
		    },
		    {
			xtype: 'proxmoxintegerfield',
			fieldLabel: gettext('Sockets'),
			name: 'sockets',
			reference: 'socketsField',
			minValue: 1,
			maxValue: 4,
			allowBlank: true,
			hidden: me.vmtype !== 'qemu',
			disabled: me.vmtype !== 'qemu',
		    }],
		},
	    ],
	});

	let title = gettext('Restore') + ": " + (me.vmtype === 'lxc' ? 'CT' : 'VM');
	if (me.vmid) {
	    title = `${gettext('Overwrite')} ${title} ${me.vmid}`;
	}

	Ext.apply(me, {
	    title: title,
	    items: [
		{
		    xtype: 'form',
		    bodyPadding: 10,
		    border: false,
		    fieldDefaults: {
			labelWidth: 100,
			anchor: '100%',
		    },
		    items: items,
		},
	    ],
	    buttons: [
		{
		    text: gettext('Restore'),
		    reference: 'doRestoreBtn',
		    handler: 'doRestore',
		},
	    ],
	});

	me.callParent();
    },
});
