using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using WebSocketSharp;
using WebSocketSharp.Server;
using static WSCF.Reflect_OBJ_INTERFACE;

namespace WSCF
{
    /// <summary>
    /// obj 服务代理;
    /// 1.如果代理的对象为 INotifyPropertyChanged, 对象内的 property 改变，能推送给客户端( [JsonIgnore] 除外);
    /// 2.代理的对象不为INotifyPropertyChanged, 但 对象内的 property 
    ///     a.是 [PropertyPush], 
    ///     b.且是 INotifyPropertyChanged, 
    ///     c.且 只能是get,不能有set,
    /// 那这个 property 内的 子property 改变，也会推送给 客户端 且 子property 是 [PropertyPush]，会继续向下全部注册 PropertyChanged,
    /// 也推送给 客户端;
    /// 3. 客户端 可以通过 Call(.....) 调用 服务 的function,  function返回的内容，需要通过[Call(...)] 定义; 且function 必须是
    /// void function(object param1, object param2,object paramN, AsyncCBHandler asyncDelegate, object asyncContext);
    /// 必须有参数 AsyncCBHandler asyncDelegate, object asyncContext， 名字不能改。 前面的 param1~paramN， 多少个都行
    /// 4. 服务中的event, 通过 [Push(...)] 可以推送给客户端， 但event 只能是 EventHandler
    /// [Push(typeof(BulkDBTempFrameChangedEventArgs))]
    ///  public event EventHandler TempFrameChanged;
    ///  
    /// </summary>
    public class Reflect_Proxy:WebSocketBehavior, IDisposable
    {
        /// <summary>
        /// 服务器中， 提供的全部服务
        /// </summary>
        protected WsServiceProxy Proxy;

        public Reflect_Proxy()
        {

        }
        public void Init(Type interfaceType, INotifyPropertyChanged obj)
        {
            var proxy = new WsServiceProxy();
            proxy.Init(interfaceType, obj);
            proxy.SetSendEx(SendTo);
            Proxy = proxy;
        }

        protected override void OnMessage(MessageEventArgs e)
        {
            if (!e.IsText)
                return;
            string json = e.Data;

            var pkgData = Newtonsoft.Json.JsonConvert.DeserializeObject<PkgData>(json);


            //客户端 向 服务器 中的 服务 请求
            Proxy.OnMessage(this, pkgData);

        }
        protected override void OnOpen()
        {
            base.OnOpen();
            Proxy.OnOpen();
        }

        protected override void OnClose(CloseEventArgs e)
        {
            base.OnClose(e);
            Proxy.OnClose();
        }
        public virtual void SendTo(string msg)
        {
            if (this.State != WebSocketState.Open)
                return;
            base.Send(msg);
        }

        public void Dispose()
        {
            Proxy.Dispose();
        }
    }
}
