using FileTime.App.Core.Exceptions; using FileTime.Core.ContentAccess; using FileTime.Core.Enums; using FileTime.Core.Models; using FileTime.Core.Timeline; using InitableService; namespace FileTime.App.ContainerSizeScanner; public class ContainerScanSnapshotProvider : ContentProviderBase, IContainerScanSnapshotProvider { private readonly ITimelessContentProvider _timelessContentProvider; private readonly IServiceProvider _serviceProvider; private readonly List _sizeScanTasks = new(); internal const string ContentProviderName = "container-size-scan"; public ContainerScanSnapshotProvider( ITimelessContentProvider timelessContentProvider, IServiceProvider serviceProvider) : base(ContentProviderName, timelessContentProvider) { _timelessContentProvider = timelessContentProvider; _serviceProvider = serviceProvider; } public override async Task GetItemByFullNameAsync( FullName fullName, PointInTime pointInTime, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown, ItemInitializationSettings itemInitializationSettings = null ) { if (fullName.Path == ContentProviderName) return this; var pathParts = fullName.Path.Split(Constants.SeparatorChar); var item = _sizeScanTasks.FirstOrDefault(t => t.SizeContainer.Name == pathParts[1])?.SizeContainer; if (pathParts.Length == 2) return item ?? throw new ItemNotFoundException(fullName); for (var i = 2; i < pathParts.Length - 1 && item != null; i++) { var childName = pathParts[i]; item = item.ChildContainers.FirstOrDefault(c => c.Name == childName); } if (item is not null) { var container = item.ChildContainers.FirstOrDefault(c => c.Name == pathParts[^1]); if (container is not null) return container; var childName = item.RealContainer.FullName?.GetChild(pathParts[^1]); if (childName is null) throw new ItemNotFoundException(fullName); return await _timelessContentProvider.GetItemByFullNameAsync( childName, pointInTime, forceResolve, forceResolvePathType, itemInitializationSettings ); } throw new ItemNotFoundException(fullName); } public override async Task GetItemByNativePathAsync( NativePath nativePath, PointInTime pointInTime, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown, ItemInitializationSettings itemInitializationSettings = default ) => await GetItemByFullNameAsync( new FullName(nativePath.Path), pointInTime, forceResolve, forceResolvePathType, itemInitializationSettings ); public override NativePath GetNativePath(FullName fullName) => new(fullName.Path); public override FullName GetFullName(NativePath nativePath) => new(nativePath.Path); public override Task GetContentAsync( IElement element, int? maxLength = null, CancellationToken cancellationToken = default) //TODO read from original source => Task.FromResult((byte[]?) null); public override bool CanHandlePath(NativePath path) => path.Path.StartsWith(ContentProviderName); public ISizeScanTask StartSizeScan(IContainer scanSizeOf) { var searchTask = _serviceProvider .GetInitableResolver(scanSizeOf) .GetRequiredService(); _sizeScanTasks.Add(searchTask); searchTask.Start(); Items.Add(new AbsolutePath(_timelessContentProvider, searchTask.SizeContainer)); return searchTask; } }