using Opc.Ua;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Adapters;

namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Tests.Fakes;

internal sealed class FakeEndpointDiscovery : IEndpointDiscovery
{
    /// <summary>Gets or sets a value indicating whether SelectEndpoint should throw an exception.</summary>
    public bool ThrowOnSelect { get; set; }
    /// <summary>Gets the number of times SelectEndpoint has been called.</summary>
    public int SelectCallCount { get; private set; }
    /// <summary>Gets the last endpoint URL passed to SelectEndpoint.</summary>
    public string? LastEndpointUrl { get; private set; }

    /// <summary>Selects an endpoint for the given configuration and URL, optionally throwing an exception.</summary>
    /// <param name="config">The application configuration.</param>
    /// <param name="endpointUrl">The endpoint URL to select.</param>
    /// <param name="requestedMode">The requested security mode.</param>
    /// <returns>The selected endpoint description.</returns>
    public EndpointDescription SelectEndpoint(ApplicationConfiguration config, string endpointUrl,
        MessageSecurityMode requestedMode)
    {
        SelectCallCount++;
        LastEndpointUrl = endpointUrl;

        if (ThrowOnSelect)
            throw new InvalidOperationException($"No endpoint found for {endpointUrl}");

        return new EndpointDescription
        {
            EndpointUrl = endpointUrl,
            SecurityMode = requestedMode,
            SecurityPolicyUri = requestedMode == MessageSecurityMode.None
                ? SecurityPolicies.None
                : SecurityPolicies.Basic256Sha256,
            Server = new ApplicationDescription
            {
                ApplicationName = "FakeServer",
                ApplicationUri = "urn:localhost:FakeServer"
            }
        };
    }
}