using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace ZB.MOM.NatsNet.Server.Auth;

/// <summary>
/// Provides JetStream encryption key management via the Trusted Platform Module (TPM).
/// Windows only — non-Windows platforms throw <see cref="PlatformNotSupportedException"/>.
/// </summary>
/// <remarks>
/// On Windows, the full implementation requires the Tpm2Lib NuGet package and accesses
/// the TPM to seal/unseal keys using PCR-based authorization. The sealed public and
/// private key blobs are persisted to disk as JSON.
/// </remarks>
public static class TpmKeyProvider
{
    /// <summary>
    /// Loads (or creates) the JetStream encryption key from the TPM.
    /// On first call (key file does not exist), generates a new NKey seed, seals it to the
    /// TPM, and writes the blobs to <paramref name="jsKeyFile"/>.
    /// On subsequent calls, reads the blobs from disk and unseals them using the TPM.
    /// </summary>
    /// <param name="srkPassword">Storage Root Key password (may be empty).</param>
    /// <param name="jsKeyFile">Path to the persisted key blobs JSON file.</param>
    /// <param name="jsKeyPassword">Password used to seal/unseal the JetStream key.</param>
    /// <param name="pcr">PCR index to bind the authorization policy to.</param>
    /// <returns>The JetStream encryption key seed string.</returns>
    /// <exception cref="PlatformNotSupportedException">Thrown on non-Windows platforms.</exception>
    public static string LoadJetStreamEncryptionKeyFromTpm(
        string srkPassword,
        string jsKeyFile,
        string jsKeyPassword,
        int pcr)
    {
        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            throw new PlatformNotSupportedException("TPM functionality is not supported on this platform.");

        // Windows implementation requires Tpm2Lib NuGet package.
        // Add <PackageReference Include="Tpm2Lib" Version="*" /> to the .csproj
        // under a Windows-conditional ItemGroup before enabling this path.
        throw new PlatformNotSupportedException(
            "TPM functionality is not supported on this platform. " +
            "On Windows, add Tpm2Lib NuGet package and implement via tpm2.OpenTPM().");
    }
}

/// <summary>
/// Persisted TPM key blobs stored on disk as JSON.
/// </summary>
internal sealed class NatsPersistedTpmKeys
{
    [JsonPropertyName("version")]
    public int Version { get; set; }

    [JsonPropertyName("private_key")]
    public byte[] PrivateKey { get; set; } = [];

    [JsonPropertyName("public_key")]
    public byte[] PublicKey { get; set; } = [];
}
