using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Security.Cryptography;

namespace Kit.Helpers
{
    public static class SystemIOStreamExtentions
    {
        public static byte[] ReadFromStream(this Stream stream)
        {
            byte[] array = new byte[32768];
            using (MemoryStream memoryStream = new MemoryStream())
            {

                while (true)
                {
                    int num = stream.Read(array, 0, array.Length);
                    if (num <= 0)
                    {
                        break;
                    }

                    memoryStream.Write(array, 0, num);
                }

                return memoryStream.ToArray();
            }
        }

        public static string ComputeHash<THashAlgorithm>(this Stream stream) where THashAlgorithm : HashAlgorithm
        {
            // Получаем тип THashAlgorithm
            Type algorithmType = typeof(THashAlgorithm);

            // Получаем метод Create() через Reflection
            MethodInfo? createMethod = algorithmType.GetMethods(BindingFlags.Public | BindingFlags.Static).SingleOrDefault(x => x.Name == "Create" && x.GetParameters().Length == 0);

            // Проверяем, существует ли метод
            if (createMethod == null)
            {
                throw new InvalidOperationException($"Тип {algorithmType.FullName} не имеет статического метода Create().");
            }

            // Вызываем метод Create() и приводим результат к HashAlgorithm
            using (var algorithm = (THashAlgorithm)createMethod.Invoke(null, null))
            {
                var hash = BitConverter.ToString(algorithm.ComputeHash(stream)).Replace("-", "").ToLowerInvariant();
                if (stream.CanSeek) stream.Position = 0;
                return hash;
            }
        }
    }
}