using System.Text;
using ZB.MOM.WW.Secrets.Abstractions;

namespace ZB.MOM.WW.Secrets.MasterKey;

/// <summary>
/// Resolves the master key (KEK) from the file at <see cref="MasterKeyOptions.FilePath"/>. The file
/// may hold either the raw 32 key bytes, or base64 text of the key. The file is read fresh on every
/// call so a rotated file takes effect immediately.
/// </summary>
/// <remarks>
/// Precedence: if the file's raw byte count is exactly 32, those bytes are the key. Otherwise the
/// content is treated as text and base64-decoded (after trimming surrounding whitespace/newlines).
/// The base-class length check then validates the decoded result.
/// </remarks>
public sealed class FileMasterKeyProvider : MasterKeyProviderBase
{
    /// <summary>Creates the provider bound to <paramref name="options"/>.</summary>
    /// <param name="options">The master-key configuration (requires <see cref="MasterKeyOptions.FilePath"/>).</param>
    public FileMasterKeyProvider(MasterKeyOptions options) : base(options)
    {
    }

    /// <inheritdoc />
    protected override byte[] ResolveKeyBytes()
    {
        string? path = Options.FilePath;
        if (string.IsNullOrEmpty(path))
        {
            throw new MasterKeyUnavailableException("Master key file path is not configured.");
        }

        if (!File.Exists(path))
        {
            throw new MasterKeyUnavailableException($"Master key file '{path}' does not exist.");
        }

        byte[] raw = File.ReadAllBytes(path);

        // Raw 32-byte file: those bytes ARE the key.
        if (raw.Length == KeySizeBytes)
        {
            return raw;
        }

        // Otherwise treat the content as base64 text.
        string text = Encoding.UTF8.GetString(raw).Trim();
        try
        {
            return Convert.FromBase64String(text);
        }
        catch (FormatException ex)
        {
            throw new MasterKeyUnavailableException(
                $"Master key file '{path}' is neither raw 32 bytes nor valid base64: {ex.Message}");
        }
    }
}
