using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace Sozsoft.Platform.Data.Seeds;
///
/// Component'in designer dokumanindaki (Props) Data sekmesi endpoint'lerini cozup
/// CRUD endpoint katalogu ile eslestiren ortak mantik.
///
/// Cozum kaydetme sirasinda (CustomComponentAppService) katalogu veritabanindan okur;
/// boylece DataSources sutunu tasarimci dokumanindan tutarli sekilde uretilir.
///
///
public static class CustomComponentDataSourceResolver
{
private static readonly JsonSerializerOptions JsonReadOptions = new()
{
PropertyNameCaseInsensitive = true
};
/// Eslestirmede kullanilan CRUD endpoint tanimi.
public sealed class CrudEndpointReference
{
public string EntityName { get; set; } = string.Empty;
public string Method { get; set; } = string.Empty;
public string Path { get; set; } = string.Empty;
public string OperationType { get; set; } = string.Empty;
}
///
/// Props icindeki visualDesigner.dataSources listesini okur ve her kaydi method + path
/// ile icinde arar. Eslesmeyen (elle yazilmis ya da custom)
/// endpoint'ler de listede kalir; yalnizca entity/seed dosyasi alanlari bos gelir.
///
public static List Resolve(
string? props,
IReadOnlyCollection endpoints)
{
var documentSources = ParseDocumentDataSources(props);
if (documentSources.Count == 0)
{
return [];
}
var resolved = new List();
foreach (var source in documentSources)
{
var method = (source.Method ?? string.Empty).Trim().ToUpperInvariant();
var url = (source.Url ?? string.Empty).Trim();
if (url.Length == 0)
{
continue;
}
// Ayni method + path birden fazla bilesene baglanmis olabilir; tekrarlari eleriz.
if (resolved.Exists(x => x.Method == method && string.Equals(x.Url, url, StringComparison.OrdinalIgnoreCase)))
{
continue;
}
var endpoint = endpoints.FirstOrDefault(x =>
string.Equals(x.Method?.Trim(), method, StringComparison.OrdinalIgnoreCase) &&
string.Equals(x.Path?.Trim(), url, StringComparison.OrdinalIgnoreCase));
resolved.Add(new CustomComponentSeedDataSourceDto
{
Name = (source.Name ?? string.Empty).Trim(),
Method = method,
Url = url,
ResponsePath = string.IsNullOrWhiteSpace(source.ResponsePath) ? null : source.ResponsePath.Trim(),
EntityName = endpoint?.EntityName,
OperationType = endpoint?.OperationType,
SeedFile = endpoint == null
? null
: $"{SeedPathResolver.CrudFolder}/{endpoint.EntityName}.json"
});
}
return resolved;
}
/// Props JSON'undaki designer dokumanindan yalnizca dataSources dizisini ayiklar.
private static List ParseDocumentDataSources(string? props)
{
if (string.IsNullOrWhiteSpace(props))
{
return [];
}
try
{
using var document = JsonDocument.Parse(props);
if (!document.RootElement.TryGetProperty("visualDesigner", out var designer) ||
designer.ValueKind != JsonValueKind.Object ||
!designer.TryGetProperty("dataSources", out var dataSources) ||
dataSources.ValueKind != JsonValueKind.Array)
{
return [];
}
return JsonSerializer.Deserialize>(dataSources.GetRawText(), JsonReadOptions) ?? [];
}
catch (JsonException)
{
return [];
}
}
/// Designer dokumanindaki tek bir data source kaydi.
private sealed class DesignerDataSourceDto
{
public string? Name { get; set; }
public string? Method { get; set; }
public string? Url { get; set; }
public string? ResponsePath { get; set; }
}
}