using ThingsGateway.NewLife.Log;
using ThingsGateway.NewLife.Net;

namespace ThingsGateway.NewLife.Caching.Queues;

/// <summary>消息队列基类</summary>
public abstract class QueueBase : RedisBase
{
    #region 属性
    /// <summary>追踪名。默认为Key，主要用于解决动态Topic导致产生大量埋点的问题</summary>
    public String TraceName { get; set; }

    /// <summary>是否在消息报文中自动注入TraceId。TraceId用于跨应用在生产者和消费者之间建立调用链，默认true</summary>
    public Boolean AttachTraceId { get; set; } = true;

    /// <summary>失败时抛出异常。默认false</summary>
    public Boolean ThrowOnFailure { get; set; } = false;

    /// <summary>发送消息失败时的重试次数。默认3次</summary>
    public Int32 RetryTimesWhenSendFailed { get; set; } = 3;

    /// <summary>重试间隔。默认1000ms</summary>
    public Int32 RetryIntervalWhenSendFailed { get; set; } = 1000;

    /// <summary>消息队列主题</summary>
    public String Topic => Key;

    /// <summary>用于埋点名的主机</summary>
    protected String _traceHost;
    #endregion

    #region 构造
    /// <summary>实例化延迟队列</summary>
    /// <param name="redis"></param>
    /// <param name="key"></param>
    public QueueBase(Redis redis, String key) : base(redis, key)
    {
        TraceName = key;

        // 计算埋点主机名
        _traceHost = redis.Name;
        if (_traceHost.IsNullOrEmpty() || _traceHost.EqualIgnoreCase("Redis", "FullRedis"))
        {
            var svr = redis.Server;
            if (!svr.IsNullOrEmpty())
            {
                var p = svr.IndexOfAny([',', ';']);
                if (p > 0) svr = svr[..p];
                var uri = new NetUri(svr);
                _traceHost = uri.Host ?? uri.Address.ToString();
            }
        }
    }
    #endregion

    #region 方法
    /// <summary>验证失败</summary>
    /// <param name="span"></param>
    protected void ValidWhenSendFailed(ISpan? span)
    {
        var ex = new InvalidOperationException($"发布到队列[{Topic}]失败！");
        span?.SetError(ex, null);

        if (ThrowOnFailure) throw ex;
    }
    #endregion
}