using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PayRollBLL.SAP.Config;
using System;
using System.Linq;
using System.Text;
using System.Text.Json;
namespace PayRollBLL.SAP.Audit
{
///
/// Writes one log file per day to the configured AuditLogDirectory.
///
/// File naming: SAP_Declaration_2026-05-22.log
/// Each file contains REQUEST blocks (payload + parameters) and
/// RESPONSE blocks (HTTP status + SAP message + raw body), timestamped to the millisecond.
///
public class SapDeclarationAuditLog : ISapDeclarationAuditLog
{
private readonly ILogger _logger;
public SapDeclarationAuditLog(
IOptions options,
ILogger logger)
{
_logger = logger;
}
// ── Public API ────────────────────────────────────────────────────────────────
public void LogRequest(
int infotype,
int declarationId,
int employeeId,
int periodId,
string endpointPath,
string description,
string jsonPayload)
{
var sb = new StringBuilder();
string ts = Ts();
string label = Label(infotype, description, endpointPath);
sb.AppendLine();
sb.AppendLine($"â–¶ REQUEST {ts} Infotype {infotype}");
sb.AppendLine(ThinBar());
sb.AppendLine($" Infotype : {infotype} ({description})");
sb.AppendLine($" Endpoint : {endpointPath}");
sb.AppendLine($" DeclarationId : {declarationId}");
sb.AppendLine($" EmployeeId : {employeeId}");
sb.AppendLine($" PeriodId : {periodId}");
sb.AppendLine(ThinBar());
sb.AppendLine(" PAYLOAD:");
sb.AppendLine(Indent(TryPrettyPrint(jsonPayload)));
sb.AppendLine(ThickBar());
Write(sb.ToString());
}
public void LogResponse(
int infotype,
string endpointPath,
string description,
int httpStatus,
bool isSuccess,
string message,
string responseBody)
{
var sb = new StringBuilder();
string ts = Ts();
string status = isSuccess ? "SUCCESS ✔" : "FAILED ✘";
sb.AppendLine();
sb.AppendLine($"â—€ RESPONSE {ts} Infotype {infotype} HTTP {httpStatus} {status}");
sb.AppendLine(ThinBar());
sb.AppendLine($" Infotype : {infotype} ({description})");
sb.AppendLine($" Endpoint : {endpointPath}");
sb.AppendLine($" Message : {message}");
sb.AppendLine(ThinBar());
sb.AppendLine(" SAP RESPONSE BODY:");
sb.AppendLine(Indent(TryPrettyPrint(responseBody)));
sb.AppendLine(ThickBar());
Write(sb.ToString());
}
// ── Internal helpers ──────────────────────────────────────────────────────────
private void Write(string content)
{
// Route through ILogger so the audit entry is captured by the configured sink
// (Serilog file/stdout/aggregator) rather than a pod-local file.
_logger.LogInformation("SAP Declaration Audit: {AuditEntry}", content);
}
private static string TryPrettyPrint(string json)
{
if (string.IsNullOrWhiteSpace(json)) return "(empty)";
try
{
using var doc = JsonDocument.Parse(json);
return JsonSerializer.Serialize(
doc.RootElement,
new JsonSerializerOptions { WriteIndented = true });
}
catch
{
return json;
}
}
private static string Indent(string text)
{
if (string.IsNullOrWhiteSpace(text)) return " (empty)";
return string.Join(
Environment.NewLine,
text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)
.Select(line => " " + line));
}
private static string Label(int infotype, string description, string endpointPath) =>
string.IsNullOrWhiteSpace(description)
? $"IT{infotype} | {endpointPath}"
: $"IT{infotype} {description} | {endpointPath}";
private static string Ts() => DateTime.UtcNow.ToString("dd-MMM-yyyy HH:mm:ss.fff");
private static string ThinBar() => new('─', 84);
private static string ThickBar() => new('═', 84);
}
}