using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace NetworkResurrector.Server.Application.Services
{
    public class PingService : IPingService
    {
        /// <summary>
        /// Ping machine by IP
        /// https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ping?redirectedfrom=MSDN&view=net-5.0
        /// </summary>
        /// <param name="ipAddressOrMachineName"></param>
        /// <returns>(bool success, string status)</returns>
        public async Task<(bool success, string status)> PingMachine(string ipAddressOrMachineName)
        {
            var ping = new Ping();

            // Use the default Ttl value which is 128,
            // but change the fragmentation behavior.
            PingOptions options = new PingOptions
            {
                DontFragment = true
            };

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 120;

            PingReply reply = await ping.SendPingAsync(ipAddressOrMachineName, timeout, buffer, options);

            if (reply.Status == IPStatus.Success)
            {
                var builder = new StringBuilder();
                builder.AppendLine($"Machine '{ipAddressOrMachineName}' has responded to ping.");

                builder.AppendLine($"Address: {reply.Address}");
                builder.AppendLine($"RoundTrip time: {reply.RoundtripTime}");
                builder.AppendLine($"Time to live: {reply.Options.Ttl}");
                builder.AppendLine($"Don't fragment: {reply.Options.DontFragment}");
                builder.AppendLine($"Buffer size: {reply.Buffer.Length}");

                return (true, builder.ToString());
            }
            else
                return (false, $"Machine '{ipAddressOrMachineName}' does not respond to ping. Status: {reply.Status}");
        }
    }
}
