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

    public static class Lz4Compression
    {
        public delegate int Decode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength);
        public delegate int Encode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength, int level);
        public delegate int MaximumOutputSize(int length);

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

                var definedTypes = assembly.DefinedTypes.ToArray();

                var lz4Codec = FindLZ4Codec(definedTypes);
                var lz4Level = FindLZ4Level(definedTypes);

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

                var decode = FindDecode(methods);
                var encode = FindEncode(methods, lz4Level);
                var maximumOutputSize = FindMaximumOutputSize(methods);

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

            compressorFactory = null;
            decompressorFactory = null;

            return false;
        }

        private static TypeInfo FindLZ4Codec(IEnumerable<TypeInfo> types)
        {
            const string fullName = "K4os.Compression.LZ4.LZ4Codec";

            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 TypeInfo FindLZ4Level(IEnumerable<TypeInfo> types)
        {
            const string fullName = "K4os.Compression.LZ4.LZ4Level";

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

                if (type.IsPublic && type.IsEnum && Enum.GetUnderlyingType(type) == typeof(int))
                    return type;

                break;
            }

            throw new Exception($"{fullName} as a public enum with an int backing 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(int))
                    continue;

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

                if (parameters[0].ParameterType != typeof(byte[]) ||
                    parameters[1].ParameterType != typeof(int) ||
                    parameters[2].ParameterType != typeof(int) ||
                    parameters[3].ParameterType != typeof(byte[]) ||
                    parameters[4].ParameterType != typeof(int) ||
                    parameters[5].ParameterType != typeof(int))
                    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, Type lz4Level)
        {
            const string name = "Encode";

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

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

                if (parameters[0].ParameterType != typeof(byte[]) ||
                    parameters[1].ParameterType != typeof(int) ||
                    parameters[2].ParameterType != typeof(int) ||
                    parameters[3].ParameterType != typeof(byte[]) ||
                    parameters[4].ParameterType != typeof(int) ||
                    parameters[5].ParameterType != typeof(int) ||
                    parameters[6].ParameterType != lz4Level)
                    continue;

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

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

        private static MaximumOutputSize FindMaximumOutputSize(MethodInfo[] methods)
        {
            const string name = "MaximumOutputSize";

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

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

                if (parameters[0].ParameterType != typeof(int))
                    continue;

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

            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)
        {
            return (source, size) =>
            {
                var decompressed = new byte[size];
                var sourceBytes = source.ToArray();
                var bytesDecompressed = decompress(sourceBytes, 0, sourceBytes.Length, decompressed, 0, decompressed.Length);
                if (size == bytesDecompressed)
                    return new ReadOnlySequence<byte>(decompressed);

                throw new CompressionException($"LZ4Codec.Decode returned {bytesDecompressed} but expected {size}");
            };
        }

        private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress, MaximumOutputSize maximumOutputSize)
        {
            return (source) =>
            {
                var sourceBytes = source.ToArray();
                var compressed = new byte[maximumOutputSize(sourceBytes.Length)];
                var bytesCompressed = compress(sourceBytes, 0, sourceBytes.Length, compressed, 0, compressed.Length, 0);
                if (bytesCompressed == -1)
                    throw new CompressionException($"LZ4Codec.Encode returned -1 when compressing {sourceBytes.Length} bytes");

                return new ReadOnlySequence<byte>(compressed, 0, bytesCompressed);
            };
        }
    }
}
