using FrameworkDAL.DTO.EIPConversation; using System; using System.Collections.Generic; using System.Text; using System.Text.Json; namespace FrameworkBLL.EIPConversation.EIPHandlers.UrlResolver { public class EIPUrlResolver : IEIPUrlResolver { // ── IEIPUrlResolver ─────────────────────────────────────────────────── public string ResolveUrl(EIPApiConfig config, Dictionary variables, string baseUri) { string raw; if (!string.IsNullOrWhiteSpace(config.ServicePrefix)) { // Internal GB5 call routed through YARP gateway. // login.BaseUri already contains the installation-specific host:port. var path = SubstituteVars(config.PathTemplate ?? string.Empty, variables); raw = $"{baseUri.TrimEnd('/')}/{config.ServicePrefix.Trim('/')}/{path.TrimStart('/')}"; } else { raw = SubstituteVars(config.Url ?? string.Empty, variables); } // Append query-string params (In="query") if (config.Parameters != null) { var qs = BuildQueryString(config.Parameters, variables); if (qs.Length > 0) raw = raw + (raw.Contains('?') ? "&" : "?") + qs; } return raw; } public (string bodyJson, Dictionary extraHeaders) BuildRequest(EIPApiConfig config, Dictionary variables) { if (config.Parameters == null || config.Parameters.Count == 0) return (string.Empty, new Dictionary()); var bodyDict = new Dictionary(); var headers = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var param in config.Parameters) { var value = ResolveValue(param, variables); if (value is null) continue; switch (param.In?.ToLowerInvariant()) { case "header": headers[param.Name] = value; break; case "query": case "path": break; // handled by ResolveUrl default: // "body" bodyDict[param.Name] = value; break; } } var json = bodyDict.Count > 0 ? JsonSerializer.Serialize(bodyDict) : string.Empty; return (json, headers); } public string ResolveUrlFromPayload( Dictionary payload, Dictionary variables, string baseUri) { // New-style: ServicePrefix + PathTemplate if (payload.TryGetValue("ServicePrefix", out var spObj) && !string.IsNullOrWhiteSpace(spObj?.ToString())) { var sp = spObj.ToString()!.Trim('/'); var path = payload.TryGetValue("PathTemplate", out var ptObj) ? SubstituteVars(ptObj?.ToString() ?? string.Empty, variables) : string.Empty; return $"{baseUri.TrimEnd('/')}/{sp}/{path.TrimStart('/')}"; } // Legacy: Endpoint (relative, for CrudOperationHandler) or Url (absolute) if (payload.TryGetValue("Endpoint", out var epObj) && !string.IsNullOrWhiteSpace(epObj?.ToString())) { return epObj.ToString()!; // caller still prepends base URL if needed } if (payload.TryGetValue("Url", out var urlObj)) return SubstituteVars(urlObj?.ToString() ?? string.Empty, variables); return string.Empty; } // ── Private helpers ─────────────────────────────────────────────────── private static string? ResolveValue(EIPParamDefinitionDTO param, Dictionary vars) { return (param.Source?.ToUpperInvariant()) switch { "FIXED" => param.Value, "CONTEXT" or "INPUT" => vars.TryGetValue(param.Key ?? string.Empty, out var v) ? v?.ToString() : param.DefaultValue, _ => param.DefaultValue }; } private static string BuildQueryString( List parameters, Dictionary variables) { var sb = new StringBuilder(); foreach (var param in parameters) { if (!string.Equals(param.In, "query", StringComparison.OrdinalIgnoreCase)) continue; var value = ResolveValue(param, variables); if (value is null) continue; if (sb.Length > 0) sb.Append('&'); sb.Append(Uri.EscapeDataString(param.Name)); sb.Append('='); sb.Append(Uri.EscapeDataString(value)); } return sb.ToString(); } internal static string SubstituteVars(string template, Dictionary variables) { if (string.IsNullOrEmpty(template)) return template; foreach (var kv in variables) template = template.Replace($"{{{kv.Key}}}", kv.Value?.ToString() ?? string.Empty, StringComparison.OrdinalIgnoreCase); return template; } } }