using Edge.Core.Parser;
using Edge.Core.Parser.BinaryParser.MessageEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Edge.Core.Processor
{

    public interface IOutgoing<TRaw, TMessage> where TMessage : MessageBase
    {
        /// <summary>
        /// should fire this event when a new message is on writing
        /// </summary>
        event EventHandler<OutgoingEventArg<TMessage>> OnWriting;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request">request to remote peer, which should trigger a response from remote peer.</param>
        /// <param name="responseCapture">predict of response correlated to request, first is the request, 2nd is the pending for capture response</param>
        /// <param name="callback">when response catpured, or timed out, this callback will be called, first parameter is the request, 2nd is the captured response or null for timed out case</param>
        /// <param name="timeout">time out, by ms</param>
        void WriteAsync(TMessage request, Func<TMessage, TMessage, bool> responseCapture, Action<TMessage, TMessage> callback, int timeout);

        /// <summary>
        /// Send an outgoing message to remote device and wait an incoming (responding) message. 
        /// </summary>
        /// <param name="request">request to remote peer, which should trigger a response from remote peer.</param>
        /// <param name="responseCapture">predict of response correlated to request, first is the request, 2nd is the pending for capture response</param>
        /// <param name="timeout">time out, by ms</param>
        /// <returns>a response from remote device</returns>
        Task<TMessage> WriteAsync(TMessage request, Func<TMessage, TMessage, bool> responseCapture, int timeout);

        void Write(TMessage message);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <param name="redirectParameter"></param>
        void Write(TMessage message, object extraControlParameter);
    }

    public class OutgoingEventArg<T> : EventArgs
    {
        public T Message { get; set; }
        public object ExtraControlParameter { get; set; }
    }

    //public class BinaryOutgoing<TMessage> : Outgoing<byte[], TMessage> where TMessage : MessageTemplateBase
    //{
    //    public BinaryOutgoing(ICommunicator<byte[], TMessage> communicator) : base(communicator)
    //    {
    //    }
    //    public override void Write(TMessage message)
    //    {

    //    }
    //}
}