97 lines
2.9 KiB
C#
97 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Tornado3_2026Election.Domain;
|
|
|
|
internal readonly record struct CutDebugRecommendation(string Key, CutDebugItemKind Kind);
|
|
|
|
internal static class CutDebugRecommendationCatalog
|
|
{
|
|
private static readonly Lazy<IReadOnlyDictionary<string, CutDebugRecommendation>> Recommendations =
|
|
new(LoadRecommendations);
|
|
|
|
public static bool TryGetRecommendation(string templateId, out CutDebugRecommendation recommendation)
|
|
{
|
|
return Recommendations.Value.TryGetValue(templateId, out recommendation);
|
|
}
|
|
|
|
public static int Count => Recommendations.Value.Count;
|
|
|
|
private static IReadOnlyDictionary<string, CutDebugRecommendation> LoadRecommendations()
|
|
{
|
|
var path = FindRecommendationPath();
|
|
if (path is null || !File.Exists(path))
|
|
{
|
|
return new Dictionary<string, CutDebugRecommendation>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
var recommendations = new Dictionary<string, CutDebugRecommendation>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (var rawLine in File.ReadLines(path, Encoding.UTF8).Skip(1))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(rawLine))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var columns = rawLine.Split('\t');
|
|
if (columns.Length < 3)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var templateId = columns[0].Trim();
|
|
var key = columns[1].Trim();
|
|
if (!Enum.TryParse<CutDebugItemKind>(columns[2].Trim(), ignoreCase: true, out var kind) ||
|
|
string.IsNullOrWhiteSpace(templateId) ||
|
|
string.IsNullOrWhiteSpace(key))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
recommendations[templateId] = new CutDebugRecommendation(key, kind);
|
|
}
|
|
|
|
return recommendations;
|
|
}
|
|
|
|
private static string? FindRecommendationPath()
|
|
{
|
|
foreach (var root in EnumerateSearchRoots())
|
|
{
|
|
var candidate = Path.Combine(root, "tools", "KarismaTcpProbe", "cut-debug-recommendations.tsv");
|
|
if (File.Exists(candidate))
|
|
{
|
|
return candidate;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static IEnumerable<string> EnumerateSearchRoots()
|
|
{
|
|
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
foreach (var start in new[] { AppContext.BaseDirectory, Environment.CurrentDirectory })
|
|
{
|
|
if (string.IsNullOrWhiteSpace(start))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var directory = new DirectoryInfo(Path.GetFullPath(start));
|
|
while (directory is not null)
|
|
{
|
|
if (seen.Add(directory.FullName))
|
|
{
|
|
yield return directory.FullName;
|
|
}
|
|
|
|
directory = directory.Parent;
|
|
}
|
|
}
|
|
}
|
|
}
|