using Newtonsoft.Json;
using System;
using System.IO;
namespace GB5Shared.Config
{
///
/// Singleton that loads GB5Shared library defaults from the physical
/// gb5shared.json file published alongside every GB5 module binary.
///
/// Why a physical file (not embedded resource):
/// Operations teams and clients can change settings such as
/// by editing gb5shared.json
/// in the deployment directory and restarting the service — no recompile needed.
///
/// File location at runtime:
/// {AppContext.BaseDirectory}/gb5shared.json
/// The .NET SDK copies this file to the publish output automatically because
/// it is declared as a Content item with CopyToPublishDirectory=PreserveNewest
/// in GB5Shared.csproj.
///
/// Override behaviour (priority, highest first):
/// 1. Module's own appsettings.json → Gb5SystemDTO:SessionExpiryMinutes > 0
/// 2. gb5shared.json (this file) in the deployment directory
/// 3. Code default (15 minutes) — used when the file is absent or unreadable
///
/// Usage (read-only):
/// int minutes = GB5SharedSettings.Instance.SessionExpiryMinutes;
///
public sealed class GB5SharedSettings
{
private static GB5SharedSettings? _instance;
private static readonly object _lock = new();
// ── Settings ─────────────────────────────────────────────────────────
///
/// Master on/off switch for the session heartbeat check.
/// "Y" (default) — enforce sliding session expiry on every API call.
/// "N" — skip session check entirely (useful during debugging).
/// Change in gb5shared.json and restart the service.
///
public string SessionHeartbeatEnabled { get; set; } = "Y";
///
/// Session idle timeout in minutes.
/// uses this value
/// when the host module has not overridden Gb5SystemDTO:SessionExpiryMinutes
/// in its own appsettings.json.
/// Default (in gb5shared.json): 15.
///
public int SessionExpiryMinutes { get; set; } = 15;
// ── Singleton access ──────────────────────────────────────────────────
///
/// The shared instance, lazily loaded from gb5shared.json on first access.
/// Cached for the lifetime of the process; restart the service after editing the file.
///
public static GB5SharedSettings Instance
{
get
{
if (_instance is not null) return _instance;
lock (_lock)
{
if (_instance is not null) return _instance;
_instance = Load();
}
return _instance;
}
}
// ── Loader ────────────────────────────────────────────────────────────
private static GB5SharedSettings Load()
{
try
{
// AppContext.BaseDirectory is the publish output folder at runtime —
// the same directory where gb5shared.json is copied during dotnet publish.
string filePath = Path.Combine(AppContext.BaseDirectory, "gb5shared.json");
if (!File.Exists(filePath))
return new GB5SharedSettings(); // file absent — use in-code defaults
string json = File.ReadAllText(filePath);
return JsonConvert.DeserializeObject(json)
?? new GB5SharedSettings();
}
catch
{
// File unreadable or JSON malformed — fall back to in-code defaults.
// The middleware always has a valid expiry value regardless.
return new GB5SharedSettings();
}
}
}
}