﻿/*
 * 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.Compression
{
    using DotPulsar.Internal.Abstractions;
    using System;
    using System.Buffers;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    public static class SnappyCompression
    {
        public delegate byte[] Decode(ReadOnlySpan<byte> source);
        public delegate byte[] Encode(ReadOnlySpan<byte> source);

        public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
        {
            try
            {
                var assembly = Assembly.Load("IronSnappy");

                var definedTypes = assembly.DefinedTypes.ToArray();

                var snappy = FindSnappy(definedTypes);

                var methods = snappy.GetMethods(BindingFlags.Public | BindingFlags.Static);

                var decode = FindDecode(methods);
                var encode = FindEncode(methods);

                compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Snappy, () => new Compressor(CreateCompressor(encode)));
                decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Snappy, () => new Decompressor(CreateDecompressor(decode)));
                return true;
            }
            catch
            {
                // Ignore
            }

            compressorFactory = null;
            decompressorFactory = null;

            return false;
        }

        private static TypeInfo FindSnappy(IEnumerable<TypeInfo> types)
        {
            const string fullName = "IronSnappy.Snappy";

            foreach (var type in types)
            {
                if (type.FullName is null || !type.FullName.Equals(fullName))
                    continue;

                if (type.IsPublic && type.IsClass && type.IsAbstract && type.IsSealed)
                    return type;

                break;
            }

            throw new Exception($"{fullName} as a public and static class was not found");
        }

        private static Decode FindDecode(MethodInfo[] methods)
        {
            const string name = "Decode";

            foreach (var method in methods)
            {
                if (method.Name != name || method.ReturnType != typeof(byte[]))
                    continue;

                var parameters = method.GetParameters();
                if (parameters.Length != 1)
                    continue;

                if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
                    continue;

                return (Decode) method.CreateDelegate(typeof(Decode));
            }

            throw new Exception($"A method with the name '{name}' matching the delegate was not found");
        }

        private static Encode FindEncode(MethodInfo[] methods)
        {
            const string name = "Encode";

            foreach (var method in methods)
            {
                if (method.Name != name || method.ReturnType != typeof(byte[]))
                    continue;

                var parameters = method.GetParameters();
                if (parameters.Length != 1)
                    continue;

                if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
                    continue;

                return (Encode) method.CreateDelegate(typeof(Encode));
            }

            throw new Exception($"A method with the name '{name}' matching the delegate was not found");
        }

        private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Decode decompress)
            => (source, size) => new ReadOnlySequence<byte>(decompress(source.ToArray()));

        private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress)
            => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
    }
}
