119 lines
4.8 KiB
C#
119 lines
4.8 KiB
C#
using FileTime.Core.Models;
|
|
using FileTime.Core.Timeline;
|
|
|
|
namespace FileTime.Core.Command
|
|
{
|
|
public class CopyCommand : ITransportationCommand
|
|
{
|
|
private Action<AbsolutePath, AbsolutePath>? _copyOperation;
|
|
private Func<IContainer, string, Task<IContainer>>? _createContainer;
|
|
private TimeRunner? _timeRunner;
|
|
|
|
public IList<AbsolutePath>? Sources { get; } = new List<AbsolutePath>();
|
|
|
|
public IContainer? Target { get; set; }
|
|
|
|
public TransportMode? TransportMode { get; set; } = Command.TransportMode.Merge;
|
|
|
|
public async Task<PointInTime> SimulateCommand(PointInTime startPoint)
|
|
{
|
|
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
|
|
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
|
|
if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
|
|
|
|
var newDiffs = new List<Difference>();
|
|
|
|
_copyOperation = (_, to) =>
|
|
{
|
|
var target = to.GetParentAsAbsolutePath().Resolve();
|
|
newDiffs.Add(new Difference(
|
|
target is IElement
|
|
? DifferenceItemType.Element
|
|
: DifferenceItemType.Container,
|
|
DifferenceActionType.Create,
|
|
to
|
|
));
|
|
};
|
|
|
|
_createContainer = async (IContainer target, string name) =>
|
|
{
|
|
var newContainerDiff = new Difference(
|
|
DifferenceItemType.Container,
|
|
DifferenceActionType.Create,
|
|
AbsolutePath.FromParentAndChildName(target, name)
|
|
);
|
|
|
|
newDiffs.Add(newContainerDiff);
|
|
|
|
return (IContainer)(await newContainerDiff.AbsolutePath.Resolve())!;
|
|
};
|
|
|
|
await DoCopy(Sources, Target, TransportMode.Value);
|
|
|
|
return startPoint.WithDifferences(newDiffs);
|
|
}
|
|
|
|
public async Task Execute(Action<AbsolutePath, AbsolutePath> copy, TimeRunner timeRunner)
|
|
{
|
|
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
|
|
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
|
|
if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
|
|
|
|
_copyOperation = copy;
|
|
_createContainer = async (IContainer target, string name) => await target.CreateContainer(name);
|
|
_timeRunner = timeRunner;
|
|
|
|
await DoCopy(Sources, Target, TransportMode.Value);
|
|
}
|
|
|
|
private async Task DoCopy(
|
|
IEnumerable<AbsolutePath> sources,
|
|
IContainer target,
|
|
TransportMode transportMode)
|
|
{
|
|
if (_copyOperation == null) throw new ArgumentException("No copy operation were given.");
|
|
if (_createContainer == null) throw new ArgumentException("No container creation function were given.");
|
|
|
|
foreach (var source in sources)
|
|
{
|
|
var item = await source.Resolve();
|
|
|
|
if (item is IContainer container)
|
|
{
|
|
var targetContainer = (await target.GetContainers())?.FirstOrDefault(d => d.Name == container.Name) ?? (await _createContainer?.Invoke(target, container.Name)!);
|
|
|
|
var childDirectories = (await container.GetContainers())!.Select(d => new AbsolutePath(d));
|
|
var childFiles = (await container.GetElements())!.Select(f => new AbsolutePath(f));
|
|
|
|
await DoCopy(childDirectories.Concat(childFiles), targetContainer, transportMode);
|
|
_timeRunner?.RefreshContainer.InvokeAsync(this, new AbsolutePath(container));
|
|
}
|
|
else if (item is IElement element)
|
|
{
|
|
var targetName = element.Name;
|
|
|
|
var targetNameExists = await target.IsExists(targetName);
|
|
if (transportMode == Command.TransportMode.Merge)
|
|
{
|
|
for (var i = 0; targetNameExists; i++)
|
|
{
|
|
targetName = element.Name + (i == 0 ? "_" : $"_{i}");
|
|
}
|
|
}
|
|
else if (transportMode == Command.TransportMode.Skip && targetNameExists)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_copyOperation?.Invoke(new AbsolutePath(element), AbsolutePath.FromParentAndChildName(target, targetName));
|
|
}
|
|
}
|
|
}
|
|
|
|
public Task<CanCommandRun> CanRun(PointInTime startPoint)
|
|
{
|
|
//TODO: implement
|
|
return Task.FromResult(CanCommandRun.True);
|
|
}
|
|
}
|
|
} |