using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Dpz.Core.Public.Entity;
using Dpz.Core.Public.ViewModel.RequestEvent;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
namespace Dpz.Core.Service.Event;
public class CodeCompatibleHandler(
IRepository<CodeFileSystemEntry> codeFileSystemEntryRepository,
IRepository<CodeNote> codeNoteRepository
) : IRequestHandler<CodeCompatibleRequest>
{
public async Task Handle(CodeCompatibleRequest request, CancellationToken cancellationToken)
{
if (request.NewEntries is { Count: > 0 })
{
await HandleIncrementalAsync(request.NewEntries, cancellationToken);
return;
}
await HandleFullAsync(cancellationToken);
}
private async Task HandleIncrementalAsync(
IReadOnlyCollection<CodeCompatibleEntry> newEntries,
CancellationToken cancellationToken
)
{
var pathGroups = newEntries
.Select(x => BuildPathString(x.ParentPathSegments))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
if (pathGroups.Count == 0)
{
return;
}
var noteFilter = Builders<CodeNote>.Filter.In(x => x.Path, pathGroups);
var notes = await codeNoteRepository
.SearchFor(noteFilter)
.ToListAsync(cancellationToken);
if (notes.Count == 0)
{
return;
}
var noteMap = notes.ToDictionary(
x => BuildNoteKey(x.Path, x.Name),
StringComparer.OrdinalIgnoreCase
);
var updateList = new List<CodeFileSystemEntry>();
foreach (var entry in newEntries)
{
var key = BuildNoteKey(BuildPathString(entry.ParentPathSegments), entry.Name);
if (!noteMap.TryGetValue(key, out var note))
{
continue;
}
var entryPathSegments = BuildPathSegments(entry.ParentPathSegments, entry.Name);
var entryFilter = Builders<CodeFileSystemEntry>.Filter.Eq(
x => x.PathSegments,
entryPathSegments
);
var updatedEntry = await codeFileSystemEntryRepository
.SearchFor(entryFilter)
.FirstOrDefaultAsync(cancellationToken);
if (updatedEntry == null)
{
continue;
}
var changed = false;
if (string.IsNullOrWhiteSpace(updatedEntry.Description)
&& !string.IsNullOrWhiteSpace(note.Note))
{
updatedEntry.Description = note.Note;
changed = true;
}
if (string.IsNullOrWhiteSpace(updatedEntry.AiAnalyzeResult)
&& !string.IsNullOrWhiteSpace(note.AiAnalyzeResult))
{
updatedEntry.AiAnalyzeResult = note.AiAnalyzeResult;
changed = true;
}
if (changed)
{
updateList.Add(updatedEntry);
}
}
if (updateList.Count > 0)
{
await codeFileSystemEntryRepository.UpdateAsync(updateList, cancellationToken);
}
}
private async Task HandleFullAsync(CancellationToken cancellationToken)
{
var notes = await codeNoteRepository.SearchFor(x => true).ToListAsync(cancellationToken);
if (notes.Count == 0)
{
return;
}
var entries = await codeFileSystemEntryRepository
.SearchFor(x => true)
.ToListAsync(cancellationToken);
if (entries.Count == 0)
{
return;
}
var entryMap = entries.ToDictionary(
x => BuildPathKey(x.PathSegments),
StringComparer.OrdinalIgnoreCase
);
var updateList = new List<CodeFileSystemEntry>();
foreach (var note in notes)
{
var pathSegments = BuildPathSegments(note.Path, note.Name);
if (pathSegments.Count == 0)
{
continue;
}
var key = BuildPathKey(pathSegments);
if (!entryMap.TryGetValue(key, out var entry))
{
continue;
}
var changed = false;
if (
string.IsNullOrWhiteSpace(entry.Description)
&& !string.IsNullOrWhiteSpace(note.Note)
)
{
entry.Description = note.Note;
changed = true;
}
if (
string.IsNullOrWhiteSpace(entry.AiAnalyzeResult)
&& !string.IsNullOrWhiteSpace(note.AiAnalyzeResult)
)
{
entry.AiAnalyzeResult = note.AiAnalyzeResult;
changed = true;
}
if (changed)
{
updateList.Add(entry);
}
}
if (updateList.Count > 0)
{
await codeFileSystemEntryRepository.UpdateAsync(updateList, cancellationToken);
}
}
private static List<string> BuildPathSegments(string? path, string name)
{
var segments = new List<string>();
if (!string.IsNullOrWhiteSpace(path))
{
segments.AddRange(
path.Split(
'/',
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
)
);
}
if (!string.IsNullOrWhiteSpace(name))
{
segments.Add(name);
}
return segments;
}
private static string BuildPathKey(IEnumerable<string> segments)
{
return string.Join("/", segments);
}
private static string BuildPathString(IEnumerable<string> segments)
{
return string.Join("/", segments.Where(x => !string.IsNullOrWhiteSpace(x)));
}
private static string BuildNoteKey(string path, string name)
{
return string.Join("/", new[] { path, name }.Where(x => !string.IsNullOrWhiteSpace(x)));
}
private static List<string> BuildPathSegments(
IEnumerable<string> parentPathSegments,
string name
)
{
var segments = parentPathSegments.Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
if (!string.IsNullOrWhiteSpace(name))
{
segments.Add(name);
}
return segments;
}
}
评论加载中...