summary refs log tree commit diff
path: root/ReferenceClientProxyImplementation/Patches/Implementations/PatchSet.cs
blob: 5840e03dabc2a7eebed03cef95693cf02f8b3339 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System.Collections.Concurrent;

namespace ReferenceClientProxyImplementation.Patches.Implementations;

public class PatchSet(IServiceProvider sp)
{
    public ConcurrentDictionary<string, PatchState> ActivePatchStates { get; } = [];
    public List<IPatch> Patches { get; } = sp.GetServices<IPatch>().OrderBy(x => x.GetOrder()).ToList();

    public async Task<byte[]> ApplyPatches(string relativeName, byte[] content)
    {
        var i = 0;
        var patches = Patches
            .Where(p => p.Applies(relativeName, content))
            .OrderBy(p => p.GetOrder())
            .ToList();

        if (!patches.Any())
        {
            Console.WriteLine($"No patches required for {relativeName}!");
            return content;
        }
        
        lock (ActivePatchStates)
            ActivePatchStates[relativeName] = new()
            {
                CurrentPatch = patches[0].GetName(),
                CurrentPatchIndex = 0,
                TotalPatchCount = patches.Count
            };

        foreach (var patch in patches)
        {
            // if (patch.Applies(relativeName, content)) {
            lock (ActivePatchStates)
            {
                ActivePatchStates[relativeName].CurrentPatchIndex = patches.IndexOf(patch);
                ActivePatchStates[relativeName].CurrentPatch = patch.GetName();
            }

            var defaultColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.DarkBlue;
            Console.Write($"{relativeName,32} ==> ");
            Console.ForegroundColor = ConsoleColor.DarkGray;
            Console.WriteLine($"Running task {++i}/{patches.Count}: {patch.GetName()} (Type<{patch.GetType().Name}>)");
            Console.ForegroundColor = defaultColor;
            content = await patch.Execute(relativeName, content);
            // }
        }

        lock (ActivePatchStates)
            ActivePatchStates.Remove(relativeName, out _);
        Console.WriteLine($"Finished patching {relativeName}, {ActivePatchStates.Count} files still processing");

        return content;
    }
}

public class PatchState
{
    public required string CurrentPatch { get; set; }
    public int CurrentPatchIndex { get; set; } = 0;
    public required int TotalPatchCount { get; set; }
}