﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SNet.Net
{
    public class ProtocolManager
    {
        private Dictionary<ProtocolVersionRange, Type> ProtocolBindings = new Dictionary<ProtocolVersionRange, Type>();

        public delegate void ProtocolInitializedDelegate<T>(T protocol) where T : Protocol;

        public bool Bind<T>(ProtocolVersionRange version, ProtocolInitializedDelegate<T> onInitializedDelegate) where T : Protocol //TODO: Change to actual protocol class
        {
            if (ProtocolBindings.ContainsKey(version))
                return false;

            ProtocolBindings.Add(version, typeof(T));
            return true;
        }

        private Dictionary<ISocket, PendingSocketData> PendingSocketBuffer = new Dictionary<ISocket, PendingSocketData>();

        public void Bind(ISocket socket)
        {
            PendingSocketData pending = new PendingSocketData(socket);
            PendingSocketBuffer.Add(socket, pending);
            socket.OnDataRecieved += InternalOnSocketRecieve;
            //Keep a list of sockets, temporarily subscribe to their recieve method
            //Read 4 bytes, enough for checking their version.
            //When the 4 bytes are read, raise an event corresponding with that protocol version.
        }

        protected void InternalOnSocketRecieve(ISocket socket, byte[] data, int size)
        {


        }

        public bool Unbind(ProtocolVersionRange version)
        {
            return ProtocolBindings.Remove(version);
        }

        /// <summary>
        /// Returns the associated <see cref="Protocol"/> with the <see cref="ProtocolVersion"/>.
        /// Returns null if no <see cref="Protocol"/> was found.
        /// </summary>
        /// <param name="version"></param>
        /// <returns></returns>
        public Protocol GetProtocol(ProtocolVersion version, ISocket socket)
        {
            foreach(ProtocolVersionRange protocolVersion in ProtocolBindings.Keys)
            {
                if (protocolVersion.IsWithinRange(version))
                    return (Protocol)Activator.CreateInstance(ProtocolBindings[protocolVersion], socket);
            }
            return null;
        }
    }
}
