141 lines
5.3 KiB
C#
141 lines
5.3 KiB
C#
using RolemasterDb.ImportTool.Parsing;
|
|
|
|
namespace RolemasterDb.ImportTool;
|
|
|
|
public sealed class CriticalImportCommandRunner
|
|
{
|
|
private readonly CriticalImportManifestLoader manifestLoader = new();
|
|
private readonly ImportArtifactWriter artifactWriter = new();
|
|
private readonly PdfXmlExtractor pdfXmlExtractor = new();
|
|
private readonly CriticalSourceImageArtifactGenerator sourceImageArtifactGenerator;
|
|
private readonly StandardCriticalTableParser standardParser = new();
|
|
private readonly VariantColumnCriticalTableParser variantColumnParser = new();
|
|
private readonly GroupedVariantCriticalTableParser groupedVariantParser = new();
|
|
|
|
public CriticalImportCommandRunner()
|
|
{
|
|
sourceImageArtifactGenerator = new CriticalSourceImageArtifactGenerator(pdfXmlExtractor);
|
|
}
|
|
|
|
public async Task<int> RunAsync(ResetOptions options)
|
|
{
|
|
if (!string.Equals(options.Target, "criticals", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Console.Error.WriteLine("Only 'criticals' is supported by phase 1.");
|
|
return 1;
|
|
}
|
|
|
|
var loader = new CriticalImportLoader(ResolveDatabasePath(options.DatabasePath));
|
|
var removedTableCount = await loader.ResetCriticalsAsync();
|
|
Console.WriteLine($"Removed {removedTableCount} critical table records.");
|
|
return 0;
|
|
}
|
|
|
|
public async Task<int> RunAsync(ExtractOptions options)
|
|
{
|
|
var entry = GetManifestEntry(options.Table);
|
|
var artifactPaths = CreateArtifactPaths(entry.Slug);
|
|
await pdfXmlExtractor.ExtractAsync(ResolveRepositoryPath(entry.PdfPath), artifactPaths.XmlPath);
|
|
Console.WriteLine($"Extracted {entry.Slug} to {artifactPaths.XmlPath}");
|
|
return 0;
|
|
}
|
|
|
|
public async Task<int> RunAsync(LoadOptions options)
|
|
{
|
|
var entry = GetManifestEntry(options.Table);
|
|
var artifactPaths = CreateArtifactPaths(entry.Slug);
|
|
|
|
if (!File.Exists(artifactPaths.XmlPath))
|
|
{
|
|
Console.Error.WriteLine($"Missing XML artifact: {artifactPaths.XmlPath}");
|
|
return 1;
|
|
}
|
|
|
|
var xmlContent = await File.ReadAllTextAsync(artifactPaths.XmlPath);
|
|
var parseResult = Parse(entry, xmlContent);
|
|
await sourceImageArtifactGenerator.GenerateAsync(
|
|
ResolveRepositoryPath(entry.PdfPath),
|
|
artifactPaths,
|
|
parseResult,
|
|
CancellationToken.None);
|
|
await artifactWriter.WriteAsync(artifactPaths, parseResult, CancellationToken.None);
|
|
|
|
if (!parseResult.ValidationReport.IsValid)
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Validation failed for '{entry.Slug}'. See {artifactPaths.ValidationReportPath} for details.");
|
|
}
|
|
|
|
foreach (var warning in parseResult.ValidationReport.Warnings)
|
|
{
|
|
Console.WriteLine($"Warning: {warning}");
|
|
}
|
|
|
|
var loader = new CriticalImportLoader(ResolveDatabasePath(options.DatabasePath));
|
|
var result = await loader.LoadAsync(parseResult.Table);
|
|
|
|
Console.WriteLine(
|
|
$"Loaded {result.TableSlug}: {result.ColumnCount} columns, {result.RollBandCount} roll bands, {result.ResultCount} results.");
|
|
|
|
return 0;
|
|
}
|
|
|
|
public async Task<int> RunAsync(ImportOptions options)
|
|
{
|
|
var extractExitCode = await RunAsync(new ExtractOptions
|
|
{
|
|
DatabasePath = options.DatabasePath,
|
|
Table = options.Table
|
|
});
|
|
|
|
if (extractExitCode != 0)
|
|
{
|
|
return extractExitCode;
|
|
}
|
|
|
|
return await RunAsync(new LoadOptions
|
|
{
|
|
DatabasePath = options.DatabasePath,
|
|
Table = options.Table
|
|
});
|
|
}
|
|
|
|
private CriticalImportManifestEntry GetManifestEntry(string tableSlug)
|
|
{
|
|
var manifest = manifestLoader.Load(RepositoryPaths.Discover().ManifestPath);
|
|
return manifest.Tables
|
|
.Where(item => item.Enabled)
|
|
.SingleOrDefault(item => string.Equals(item.Slug, tableSlug.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
?? throw new InvalidOperationException($"No enabled manifest entry was found for '{tableSlug}'.");
|
|
}
|
|
|
|
private CriticalTableParseResult Parse(CriticalImportManifestEntry entry, string xmlContent)
|
|
{
|
|
if (string.Equals(entry.Family, "standard", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return standardParser.Parse(entry, xmlContent);
|
|
}
|
|
|
|
if (string.Equals(entry.Family, "variant_column", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return variantColumnParser.Parse(entry, xmlContent);
|
|
}
|
|
|
|
if (string.Equals(entry.Family, "grouped_variant", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return groupedVariantParser.Parse(entry, xmlContent);
|
|
}
|
|
|
|
throw new InvalidOperationException($"Family '{entry.Family}' is not supported by the importer.");
|
|
}
|
|
|
|
private static ImportArtifactPaths CreateArtifactPaths(string slug) =>
|
|
ImportArtifactPaths.Create(RepositoryPaths.Discover().ArtifactsRootPath, slug);
|
|
|
|
private static string ResolveDatabasePath(string? databasePath) =>
|
|
Path.GetFullPath(databasePath ?? RepositoryPaths.Discover().DefaultDatabasePath);
|
|
|
|
private static string ResolveRepositoryPath(string path) =>
|
|
Path.GetFullPath(Path.Combine(RepositoryPaths.Discover().RootPath, path));
|
|
}
|