using Opc.Ua;

namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests;

/// <summary>
/// Builds the client-side <see cref="SecurityConfiguration"/> the integration tests use to
/// open a real OPC UA session. The SDK's <c>ApplicationConfiguration.ValidateAsync</c> requires
/// the trusted-issuer / trusted-peer / rejected stores to carry an explicit <c>StorePath</c>
/// (it throws <c>TrustedIssuerCertificates StorePath must be specified</c> otherwise), so — unlike
/// a bare <c>new SecurityConfiguration()</c> — each store is rooted at a throwaway PKI directory,
/// mirroring <c>src/Client/.../DefaultApplicationConfigurationFactory.cs</c>.
/// </summary>
internal static class TestClientSecurity
{
    /// <summary>Allocates a fresh throwaway client PKI root under the temp directory.</summary>
    /// <returns>An absolute path that does not yet exist; the SDK creates the stores under it.</returns>
    public static string AllocatePkiRoot() =>
        Path.Combine(Path.GetTempPath(), $"otopcua-client-pki-{Guid.NewGuid():N}");

    /// <summary>Builds an auto-accepting client security config with Directory stores under <paramref name="pkiRoot"/>.</summary>
    /// <param name="pkiRoot">Root directory for the own / issuer / trusted / rejected stores.</param>
    /// <returns>A validated-ready <see cref="SecurityConfiguration"/>.</returns>
    public static SecurityConfiguration Build(string pkiRoot) => new()
    {
        ApplicationCertificate = new CertificateIdentifier
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = Path.Combine(pkiRoot, "own"),
        },
        TrustedIssuerCertificates = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = Path.Combine(pkiRoot, "issuer"),
        },
        TrustedPeerCertificates = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = Path.Combine(pkiRoot, "trusted"),
        },
        RejectedCertificateStore = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = Path.Combine(pkiRoot, "rejected"),
        },
        AutoAcceptUntrustedCertificates = true,
    };
}
