﻿#region License

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Numerics;
using Gremlin.Net.Process.Traversal;
using Gremlin.Net.Process.Traversal.Strategy;
using Gremlin.Net.Structure.IO.GraphBinary.Types;

namespace Gremlin.Net.Structure.IO.GraphBinary
{
    /// <summary>
    /// Provides GraphBinary serializers for different types.
    /// </summary>
    public class TypeSerializerRegistry
    {
        private readonly Dictionary<Type, ITypeSerializer> _serializerByType =
            new Dictionary<Type, ITypeSerializer>
            {
                {typeof(int), SingleTypeSerializers.IntSerializer},
                {typeof(long), SingleTypeSerializers.LongSerializer},
                {typeof(string), new StringSerializer()},
                {typeof(DateTimeOffset), DateTimeOffsetSerializer.DateSerializer},
                {typeof(GremlinType), new ClassSerializer()},
                {typeof(Type), new TypeSerializer()},
                {typeof(double), SingleTypeSerializers.DoubleSerializer},
                {typeof(float), SingleTypeSerializers.FloatSerializer},
                {typeof(Guid), new UuidSerializer()},
                {typeof(Edge), new EdgeSerializer()},
                {typeof(Path), new PathSerializer()},
                {typeof(Property), new PropertySerializer()},
                {typeof(Vertex), new VertexSerializer()},
                {typeof(VertexProperty), new VertexPropertySerializer()},
                {typeof(Barrier), EnumSerializers.BarrierSerializer},
                {typeof(Binding), new BindingSerializer()},
                {typeof(Bytecode), new BytecodeSerializer()},
                {typeof(ITraversal), new TraversalSerializer()},
                {typeof(Cardinality), EnumSerializers.CardinalitySerializer},
                {typeof(Column), EnumSerializers.ColumnSerializer},
                {typeof(Direction), EnumSerializers.DirectionSerializer},
                {typeof(Merge), EnumSerializers.MergeSerializer},
                {typeof(Operator), EnumSerializers.OperatorSerializer},
                {typeof(Order), EnumSerializers.OrderSerializer},
                {typeof(Pick), EnumSerializers.PickSerializer},
                {typeof(Pop), EnumSerializers.PopSerializer},
                {typeof(ILambda), new LambdaSerializer()},
                {typeof(P), new PSerializer(DataType.P)},
                {typeof(Scope), EnumSerializers.ScopeSerializer},
                {typeof(T), EnumSerializers.TSerializer},
                {typeof(Traverser), new TraverserSerializer()},
                {typeof(decimal), new BigDecimalSerializer()},
                {typeof(BigInteger), new BigIntegerSerializer()},
                {typeof(byte), SingleTypeSerializers.ByteSerializer},
                {typeof(byte[]), new ByteBufferSerializer()},
                {typeof(short), SingleTypeSerializers.ShortSerializer},
                {typeof(bool), SingleTypeSerializers.BooleanSerializer},
                {typeof(TextP), new PSerializer(DataType.TextP)},
                {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()},
                {typeof(char), new CharSerializer()},
                {typeof(TimeSpan), new DurationSerializer()},
            };

        private readonly Dictionary<DataType, ITypeSerializer> _serializerByDataType =
            new Dictionary<DataType, ITypeSerializer>
            {
                {DataType.Int, SingleTypeSerializers.IntSerializer},
                {DataType.Long, SingleTypeSerializers.LongSerializer},
                {DataType.String, new StringSerializer()},
                {DataType.Date, DateTimeOffsetSerializer.DateSerializer},
                {DataType.Timestamp, DateTimeOffsetSerializer.TimestampSerializer},
                {DataType.Class, new ClassSerializer()},
                {DataType.Double, SingleTypeSerializers.DoubleSerializer},
                {DataType.Float, SingleTypeSerializers.FloatSerializer},
                {DataType.List, new ListSerializer<object>()},
                {DataType.Map, new MapSerializer<object, object>()},
                {DataType.Set, new SetSerializer<HashSet<object?>, object>()},
                {DataType.Uuid, new UuidSerializer()},
                {DataType.Edge, new EdgeSerializer()},
                {DataType.Path, new PathSerializer()},
                {DataType.Property, new PropertySerializer()},
                {DataType.Vertex, new VertexSerializer()},
                {DataType.VertexProperty, new VertexPropertySerializer()},
                {DataType.Barrier, EnumSerializers.BarrierSerializer},
                {DataType.Binding, new BindingSerializer()},
                {DataType.Bytecode, new BytecodeSerializer()},
                {DataType.Cardinality, EnumSerializers.CardinalitySerializer},
                {DataType.Column, EnumSerializers.ColumnSerializer},
                {DataType.Direction, EnumSerializers.DirectionSerializer},
                {DataType.Merge, EnumSerializers.MergeSerializer},
                {DataType.Operator, EnumSerializers.OperatorSerializer},
                {DataType.Order, EnumSerializers.OrderSerializer},
                {DataType.Pick, EnumSerializers.PickSerializer},
                {DataType.Pop, EnumSerializers.PopSerializer},
                {DataType.Lambda, new LambdaSerializer()},
                {DataType.P, new PSerializer(DataType.P)},
                {DataType.Scope, EnumSerializers.ScopeSerializer},
                {DataType.T, EnumSerializers.TSerializer},
                {DataType.Traverser, new TraverserSerializer()},
                {DataType.BigDecimal, new BigDecimalSerializer()},
                {DataType.BigInteger, new BigIntegerSerializer()},
                {DataType.Byte, SingleTypeSerializers.ByteSerializer},
                {DataType.ByteBuffer, new ByteBufferSerializer()},
                {DataType.Short, SingleTypeSerializers.ShortSerializer},
                {DataType.Boolean, SingleTypeSerializers.BooleanSerializer},
                {DataType.TextP, new PSerializer(DataType.TextP)},
                {DataType.TraversalStrategy, new TraversalStrategySerializer()},
                {DataType.BulkSet, new BulkSetSerializer<List<object>>()},
                {DataType.Char, new CharSerializer()},
                {DataType.Duration, new DurationSerializer()},
            };

        private readonly Dictionary<string, CustomTypeSerializer> _serializerByCustomTypeName =
            new Dictionary<string, CustomTypeSerializer>();

        private TypeSerializerRegistry(List<CustomTypeRegistryEntry> customTypeEntries)
        {
            foreach (var entry in customTypeEntries)
            {
                _serializerByType[entry.Type] = entry.TypeSerializer;
                _serializerByCustomTypeName[entry.CustomTypeName] = entry.TypeSerializer;
            }
        }

        /// <summary>
        /// Provides a default <see cref="TypeSerializerRegistry"/> instance.
        /// </summary>
        public static readonly TypeSerializerRegistry Instance = Build().Create();

        /// <summary>
        /// Builds a <see cref="TypeSerializerRegistry"/>.
        /// </summary>
        public static Builder Build() => new Builder();

        /// <summary>
        /// Gets a serializer for the given type of the value to be serialized.
        /// </summary>
        /// <param name="valueType">Type of the value to be serialized.</param>
        /// <returns>A serializer for the provided type.</returns>
        /// <exception cref="InvalidOperationException">Thrown when no serializer can be found for the type.</exception>
        public ITypeSerializer GetSerializerFor(Type valueType)
        {
            if (_serializerByType.ContainsKey(valueType))
            {
                return _serializerByType[valueType];
            }
            
            if (IsDictionaryType(valueType, out var dictKeyType, out var dictValueType))
            {
                var serializerType = typeof(MapSerializer<,>).MakeGenericType(dictKeyType, dictValueType);
                var serializer = (ITypeSerializer?) Activator.CreateInstance(serializerType);
                _serializerByType[valueType] = serializer ??
                                               throw new IOException(
                                                   $"Cannot create a serializer for the dictionary type {valueType}.");
                return serializer;
            }

            if (IsSetType(valueType))
            {
                var memberType = valueType.GetGenericArguments()[0];
                var serializerType = typeof(SetSerializer<,>).MakeGenericType(valueType, memberType);
                var serializer = (ITypeSerializer?) Activator.CreateInstance(serializerType);
                _serializerByType[valueType] = serializer ??
                                               throw new IOException(
                                                   $"Cannot create a serializer for the set type {valueType}.");
                return serializer;
            }

            if (valueType.IsArray)
            {
                var memberType = valueType.GetElementType();
                var serializerType = typeof(ArraySerializer<>).MakeGenericType(memberType!);
                var serializer = (ITypeSerializer?) Activator.CreateInstance(serializerType);
                _serializerByType[valueType] = serializer ??
                                               throw new IOException(
                                                   $"Cannot create a serializer for the array type {valueType}.");
                return serializer;
            }

            if (IsListType(valueType))
            {
                var memberType = valueType.GetGenericArguments()[0];
                var serializerType = typeof(ListSerializer<>).MakeGenericType(memberType);
                var serializer = (ITypeSerializer?) Activator.CreateInstance(serializerType);
                _serializerByType[valueType] = serializer ??
                                               throw new IOException(
                                                   $"Cannot create a serializer for the list type {valueType}.");
                return serializer;
            }

            foreach (var supportedType in _serializerByType.Keys)
            {
                if (supportedType.IsAssignableFrom(valueType))
                {
                    var serializer = _serializerByType[supportedType];
                    _serializerByType[valueType] = serializer;
                    return serializer;
                }
            }

            throw new InvalidOperationException($"No serializer found for type '{valueType}'.");
        }

        private static bool IsDictionaryType(Type type, [NotNullWhen(returnValue: true)] out Type? keyType,
            [NotNullWhen(returnValue: true)] out Type? valueType)
        {
            var maybeInterfaceType = type
                .GetInterfaces()
                .FirstOrDefault(implementedInterfaceType => implementedInterfaceType.IsConstructedGenericType && implementedInterfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>));

            if (maybeInterfaceType is { } interfaceType)
            {
                keyType = interfaceType.GetGenericArguments()[0];
                valueType = interfaceType.GetGenericArguments()[1];

                return true;
            }

            keyType = null;
            valueType = null;

            return false;
        }

        private static bool IsSetType(Type type)
        {
            return type.GetInterfaces().Any(implementedInterface => implementedInterface.IsConstructedGenericType &&
                                                                    implementedInterface.GetGenericTypeDefinition() ==
                                                                    typeof(ISet<>));
        }

        private static bool IsListType(Type type)
        {
            return type.GetInterfaces().Any(implementedInterface => implementedInterface.IsConstructedGenericType &&
                                                                    implementedInterface.GetGenericTypeDefinition() ==
                                                                    typeof(IList<>));
        }
        
        /// <summary>
        /// Gets a serializer for the given GraphBinary type.
        /// </summary>
        /// <param name="type">The GraphBinary type that should be (de)serialized.</param>
        /// <returns>A serializer for the provided GraphBinary type.</returns>
        public ITypeSerializer GetSerializerFor(DataType type)
        {
            if (type == DataType.Custom)
                throw new ArgumentException("Custom type serializers can not be retrieved using this method");
            
            return _serializerByDataType[type];
        }
        
        /// <summary>
        /// Gets a serializer for the given custom type name.
        /// </summary>
        /// <param name="typeName">The custom type name.</param>
        /// <returns>A serializer for the provided custom type name.</returns>
        public CustomTypeSerializer GetSerializerForCustomType(string typeName)
        {
            return _serializerByCustomTypeName.TryGetValue(typeName, out var serializer)
                ? serializer
                : throw new InvalidOperationException($"No serializer found for type '{typeName}'.");
        }
        
        /// <summary>
        /// The builder of a <see cref="TypeSerializerRegistry"/>.
        /// </summary>
        public class Builder
        {
            private readonly List<CustomTypeRegistryEntry> _list = new List<CustomTypeRegistryEntry>();
        
            /// <summary>
            /// Creates the <see cref="TypeSerializerRegistry"/>.
            /// </summary>
            public TypeSerializerRegistry Create() => new TypeSerializerRegistry(_list);

            /// <summary>
            /// Adds a serializer for a custom type.
            /// </summary>
            /// <param name="type">The custom type supported by the serializer.</param>
            /// <param name="serializer">The serializer for the custom type.</param>
            public Builder AddCustomType(Type type, CustomTypeSerializer serializer)
            {
                if (serializer == null) throw new ArgumentNullException(nameof(serializer));
                if (serializer.TypeName == null)
                    throw new ArgumentException("serializer custom type name can not be null");
                
                _list.Add(new CustomTypeRegistryEntry(type, serializer));
                return this;
            }
        }

        private class CustomTypeRegistryEntry
        {
            public Type Type { get; }
            public CustomTypeSerializer TypeSerializer { get; }

            public CustomTypeRegistryEntry(Type type, CustomTypeSerializer typeSerializer)
            {
                Type = type;
                TypeSerializer = typeSerializer;
            }
            public string CustomTypeName => TypeSerializer.TypeName;
        }
    }
}