using FObjBase;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace FObjBase
{
    /// <summary>
    /// 管理全部 XxxxServiceClient 的连接关系
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
    public class FObjServiceClientManager
    {
        NLog.ILogger logger = NLog.LogManager.GetCurrentClassLogger();

        private static FObjServiceClientManager instance = null;
        /// <summary>
        /// 全局管理器
        /// </summary>
        public static FObjServiceClientManager Instance 
        {
            get {
                if (instance == null)
                {
                    instance = new FObjServiceClientManager();
                    instance.Load();
                }
                return instance;
            }
        }
        /// <summary>
        /// 连接地址
        /// </summary>
        [JsonProperty]
        public List<ConnAddr> ConnAddrs = new List<ConnAddr>();

        /// <summary>
        /// 连接到 另一个Obj系统
        /// </summary>
        /// <param name="connName"></param>
        /// <param name="fObjClient"></param>
        /// <returns></returns>
        public void Connect_to_Another_OBJSys(string connName, FObjServiceClient fObjClient) 
        {
            //找到地址
            var connaddr = ConnAddrs.Find(c => c.ConnName == connName);
            if (connaddr == null)
            {
                //没有，那就创建一个
                connaddr = new ConnAddr() { ConnName = connName, Addr = "127.0.0.1:20006" };
                ConnAddrs.Add(connaddr);
            }
            foreach (var id in fObjClient.GetIDs()) 
            {
                if (!connaddr.ClientIds.Contains(id))
                {
                    connaddr.ClientIds.Add(id);
                    connaddr.Conn = FObjSys.Current.Connect_to_Another_OBJSys(connaddr.ep, id);
                } 
            }
        }

        /// <summary>
        /// 重连
        /// </summary>
        /// <param name="connName"></param>
        /// <param name="addr"></param>
        public void ReConnect(string connName, string addr) 
        {
            //找到地址
            var connaddr = ConnAddrs.Find(c => c.ConnName == connName);
            if (connaddr == null)
            {
                //没有！！！！,失败！！！
                logger.Error($"ReConnect({connaddr},{addr}), 不能找到 ConnAddr");
                return;
            }
            connaddr.Addr = addr;

            if (connaddr.Conn != null)
            {
                var conn = connaddr.Conn;
                if (!conn.RemoteEP.Equals(connaddr.ep))
                {
                    //断开之前的连接
                    FObjSys.Current.Disconnect_to_Another_OBJSys(conn.RemoteEP, connaddr.ClientIds.ToArray());
                }
            }
            connaddr.Conn = FObjSys.Current.Connect_to_Another_OBJSys(connaddr.ep, connaddr.ClientIds.ToArray());
        }
        

        string filename = "serviceManager.json";

        /// <summary>
        /// 加载配置
        /// </summary>
        public void Load() 
        {
            if (File.Exists(filename)) 
            {
                try
                {
                    string json = File.ReadAllText(filename);
                    JsonConvert.PopulateObject(json, this);
                    if (this.ConnAddrs == null)
                        this.ConnAddrs = new List<ConnAddr>();
                }
                catch 
                {
                    
                }
            }
        }
        
        /// <summary>
        /// 保存配置
        /// </summary>
        public void Save() 
        {
            try
            {

                string json = JsonConvert.SerializeObject(this, Formatting.Indented);
                File.WriteAllText(filename, json);
            }
            catch 
            {
            
            }
        }
    }

    /// <summary>
    /// 连接地址
    /// </summary>
    [JsonObject(MemberSerialization.OptIn)]
    public class ConnAddr 
    {
        /// <summary>
        /// 连接器名称
        /// </summary>
        [JsonProperty]
        public string ConnName;

        /// <summary>
        /// 设备地址
        /// </summary>
        [JsonProperty]
        public string Addr;

        /// <summary>
        /// EndPoint
        /// </summary>
        public IPEndPoint ep 
        {
            get {
                return Misc.StringConverter.ToIPEndPoint(Addr);
            }
        }

        /// <summary>
        /// 连接
        /// </summary>
        public TCPCConn Conn;

        /// <summary>
        /// 客户端 服务代理Id
        /// </summary>
        public List<UInt32> ClientIds = new List<UInt32>();
    }
}
