using System.Text.Json;
using System.Text.Json.Serialization;
using Repoverse.Core.Model;
namespace Repoverse.Core.Generation;
///
/// Hand-authored world design (ยง83). Overrides augment procedural output; any repo
/// not listed is generated normally.
///
public sealed class Overrides
{
public sealed record Entry
{
public SemanticCategory? Category { get; init; }
public District? District { get; init; }
public BuildingArchetype? Archetype { get; init; }
public bool Landmark { get; init; }
}
private readonly Dictionary _entries;
public string Source { get; }
public Overrides(IReadOnlyDictionary entries, string source)
{
_entries = entries.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => kv.Value);
Source = source;
}
public static Overrides Empty { get; } = new(new Dictionary(), "(none)");
public static Overrides Load(string path)
{
var entries = JsonSerializer.Deserialize>(File.ReadAllText(path), Json.Options)
?? throw new InvalidDataException($"Override file '{path}' is empty.");
return new Overrides(entries, Path.GetFileName(path));
}
private Entry? Get(RepoId id) => _entries.GetValueOrDefault(id.Key);
public SemanticCategory? Category(RepoId id) => Get(id)?.Category;
public District? District(RepoId id) => Get(id)?.District;
public BuildingArchetype? Archetype(RepoId id) => Get(id)?.Archetype;
public bool Landmark(RepoId id) => Get(id)?.Landmark ?? false;
}
/// Shared serializer settings: enums as strings so manifests stay human-readable and diffable.
public static class Json
{
public static JsonSerializerOptions Options { get; } = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), new RepoIdConverter() },
};
private sealed class RepoIdConverter : JsonConverter
{
public override RepoId Read(ref Utf8JsonReader reader, Type t, JsonSerializerOptions o) => RepoId.Parse(reader.GetString()!);
public override void Write(Utf8JsonWriter writer, RepoId value, JsonSerializerOptions o) => writer.WriteStringValue($"{value.Owner}/{value.Name}");
}
}