using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Threading;

namespace LJLib.TcpHandle
{
    internal abstract class TcpHandler
    {
        public TcpHandler(TcpClient client)
        {
            _client = client;
            _ns = _client.GetStream();
            _reader = new BinaryReader(_ns);
            _writer = new BinaryWriter(_ns);
        }

        protected TcpClient _client = null;
        protected NetworkStream _ns = null;
        protected BinaryReader _reader = null;
        protected BinaryWriter _writer = null;

        private bool _is_server = true;

        public TcpClient SetAsClient()
        {
            if (!_is_server)
            {
                throw new Exception("当前连接已经退出服务模式");
            }
            _is_server = false;
            return _client;
        }

        public void Handle()
        {
            var dt = DateTime.Now;
            // 客户端响应
            try
            {
                while (_is_server)
                {
                    if (!_client.Connected)
                    {
                        return;
                    }
                    if (_ns.DataAvailable)
                    {
                        dt = DateTime.Now;
                        DataArrived();
                        dt = DateTime.Now;
                    }
                    else
                    {
                        if (_client.Client.Poll(1000, SelectMode.SelectRead) && !_ns.DataAvailable)
                        {
                            return;
                        }
                        // 3分钟无数据接收则断开连接
                        if (DateTime.Now > dt.AddSeconds(180))
                        {
                            Trace.Write(string.Format("3分钟无数据接收则断开连接:{0}秒", (DateTime.Now - dt).TotalSeconds));
                            return;
                        }
                        Thread.Sleep(100);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.Write(string.Format("用时:{0}秒,异常:{1}", (DateTime.Now - dt).TotalSeconds, ex.ToString()));
            }
            finally
            {
                if (_is_server)
                {
                    Thread.Sleep(1000);
                    using (_client)
                    using (_ns)
                    using (_reader)
                    using (_writer)
                    {
                    }
                    OnClosed();
                }
            }
        }

        protected abstract void DataArrived();
        protected virtual void OnClosed() { }
    }
}
