// <copyright file="UdpReader.cs" company="IGORock Software">
// Copyright (c) IGORock Software. All rights reserved.
// </copyright>
// <author>Igor Kozlov</author>

namespace Forwarder.Modules.Ademco;

using System.Net;
using System.Net.Sockets;

using CSharpFunctionalExtensions;

using Serilog;

/// <summary>
/// Читает сообщения из UDP порта.
/// </summary>
internal sealed class UdpReader : IDisposable
{
	private readonly UdpClient _client;

	/// <summary>
	/// Прослушиваемый порт.
	/// </summary>
	public ushort Port { get; }

	/// <summary>
	/// Initializes a new instance of the <see cref="UdpReader"/> class.
	/// </summary>
	/// <param name="port">Порт прослушивания.</param>
	public UdpReader(ushort port)
	{
		_client = new UdpClient(port);
		_client.Client.ReceiveTimeout = 10_000;
		_client.Client.SendTimeout = 10_000;
		Port = port;
	}

	/// <summary>
	/// Читает сообщение из UDP порта.
	/// </summary>
	/// <param name="cancellationToken">Токен отмены.</param>
	/// <returns>Результат чтения.</returns>
	public async Task<Result<DataReadResult>> Read(CancellationToken cancellationToken)
	{
		try
		{
			var data = await _client.ReceiveAsync(cancellationToken);
			return Result.Success(new DataReadResult(data.RemoteEndPoint, data.Buffer));
		}
		catch (Exception ex)
		{
			Log.Error(ex, "UdpReader reading error");
			return Result.Failure<DataReadResult>(ex.Message);
		}
	}

	/// <summary>
	/// Отправляет сообщение в UDP порт.
	/// </summary>
	/// <param name="data">Данные.</param>
	/// <param name="endPoint">Конечная точка.</param>
	public void Write(byte[] data, IPEndPoint endPoint)
	{
		_ = _client.Send(data, data.Length, endPoint);
	}

	/// <inheritdoc />
	public void Dispose()
	{
		_client?.Dispose();
	}
}
