﻿/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace DotPulsar.Internal;

using Abstractions;
using PulsarApi;
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public sealed class PingPongHandler : IAsyncDisposable
{
    private readonly IConnection _connection;
    private readonly TimeSpan _keepAliveInterval;
    private readonly Timer _timer;
    private readonly CommandPing _ping;
    private readonly CommandPong _pong;
    private long _lastCommand;

    public PingPongHandler(IConnection connection, TimeSpan keepAliveInterval)
    {
        _connection = connection;
        _keepAliveInterval = keepAliveInterval;
        _timer = new Timer(Watch);
        _timer.Change(_keepAliveInterval, TimeSpan.Zero);
        _ping = new CommandPing();
        _pong = new CommandPong();
        _lastCommand = Stopwatch.GetTimestamp();
    }

    public bool Incoming(BaseCommand.Type commandType)
    {
        Interlocked.Exchange(ref _lastCommand, Stopwatch.GetTimestamp());

        if (commandType == BaseCommand.Type.Ping)
        {
            Task.Factory.StartNew(() => SendPong());
            return true;
        }

        return commandType == BaseCommand.Type.Pong;
    }

    private void Watch(object? state)
    {
        try
        {
            var lastCommand = Interlocked.Read(ref _lastCommand);
            var now = Stopwatch.GetTimestamp();
            var elapsed = TimeSpan.FromSeconds((now - lastCommand) / Stopwatch.Frequency);
            if (elapsed >= _keepAliveInterval)
            {
                Task.Factory.StartNew(() => SendPing());
                _timer.Change(_keepAliveInterval, TimeSpan.Zero);
            }
            else
                _timer.Change(_keepAliveInterval.Subtract(elapsed), TimeSpan.Zero);
        }
        catch
        {
            // Ignore
        }
    }

    private async Task SendPing()
    {
        try
        {
            await _connection.Send(_ping, default).ConfigureAwait(false);
        }
        catch { }
    }

    private async Task SendPong()
    {
        try
        {
            await _connection.Send(_pong, default).ConfigureAwait(false);
        }
        catch { }
    }

#if NETSTANDARD2_0
    public ValueTask DisposeAsync()
    {
        _timer.Dispose();
        return new ValueTask();
    }
#else
    public async ValueTask DisposeAsync()
    {
        await _timer.DisposeAsync().ConfigureAwait(false);
    }
#endif
}
