using AsyncEvent; using FileTime.Core.Models; using FileTime.Core.Timeline; namespace FileTime.Core.Command { public class DeleteCommand : IExecutableCommand { private Func? _deleteContainer; private Func? _deleteElement; public int Progress => 100; public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); public IList ItemsToDelete { get; } = new List(); public string DisplayLabel { get; } = "DeleteCommand"; public bool HardDelete { get; set; } public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); public async Task SimulateCommand(PointInTime startPoint) { var newDifferences = new List(); _deleteContainer = (c) => { newDifferences.Add(new Difference( DifferenceActionType.Delete, new AbsolutePath(c) )); return Task.CompletedTask; }; _deleteElement = (e) => { newDifferences.Add(new Difference( DifferenceActionType.Delete, new AbsolutePath(e) )); return Task.CompletedTask; }; foreach (var item in ItemsToDelete) { await TraverseTree((await item.ResolveAsync())!); } return startPoint.WithDifferences(newDifferences); } public async Task Execute(TimeRunner timeRunner) { _deleteContainer = async (c) => { await c.Delete(HardDelete); await timeRunner.RefreshContainer.InvokeAsync(this, new AbsolutePath(c)); }; _deleteElement = async (e) => await e.Delete(HardDelete); foreach (var item in ItemsToDelete) { await TraverseTree((await item.ResolveAsync())!); } } private async Task TraverseTree(IItem item) { if (item is IContainer container) { if (!HardDelete && container.SupportsDirectoryLevelSoftDelete) { if (_deleteContainer != null) await _deleteContainer.Invoke(container); } else { foreach (var child in (await container.GetItems())!) { await TraverseTree(child); } if (_deleteContainer != null) await _deleteContainer.Invoke(container); } } else if (item is IElement element) { if (_deleteElement != null) await _deleteElement.Invoke(element); } } public async Task CanRun(PointInTime startPoint) { var result = CanCommandRun.True; foreach (var itemPath in ItemsToDelete) { var resolvedItem = await itemPath.ResolveAsync(); if (resolvedItem != null && ( resolvedItem.CanDelete == SupportsDelete.False || (resolvedItem.CanDelete == SupportsDelete.HardDeleteOnly && !HardDelete) ) ) { result = CanCommandRun.Forceable; } } return result; } } }