﻿/*
 * 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);
            };
        }
    }
}
