using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using System.Runtime.Serialization;
using System.IO.Compression;
using System.Collections;
using System.Threading;

namespace Core.Mes.Common
{
    public class Utility
    {
        #region dataset to byte[]
        /// <summary>
        /// 序列化数据集
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static byte[] SerializeDataSet(DataSet ds)
        {
            byte[] buffer = null;
            ds.RemotingFormat = SerializationFormat.Binary;
            MemoryStream ms = new MemoryStream();
            IFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, ds);
            ds.Clear();
            ds.Dispose();
            ds = null;

            buffer = ms.ToArray();
            ms.Close();
            ms.Dispose();
            ms = null;
            return buffer;
        }

        /// <summary>
        /// 反序列化数据集
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static DataSet ReSerializable(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer);
            Array.Resize(ref buffer, 0);

            IFormatter bf = new BinaryFormatter();
            object obj = bf.Deserialize(ms);
            DataSet ds = (DataSet)obj;
            ms.Close();
            ms.Dispose();
            return ds;
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static byte[] SerializeObject(Object obj)
        {
            byte[] buffer = null;
            MemoryStream ms = new MemoryStream();
            IFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);

            buffer = ms.ToArray();
            ms.Close();
            ms.Dispose();
            ms = null;
            return buffer;
        }
        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Object ReSerializeObject(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer);
            IFormatter bf = new BinaryFormatter();
            object obj = bf.Deserialize(ms);

            ms.Close();
            ms.Dispose();
            return obj;
        }
        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static byte[] SerializeAndCompressObject(Object obj)
        {
            byte[] buffer = null;
            MemoryStream ms = new MemoryStream();
            IFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            buffer = ms.ToArray();
            ms.Close();
            ms.Dispose();
            ms = null;
            return CompressBytes(buffer);
        }
        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Object ReSerializeCompressedObject(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(Decompress(buffer));
            IFormatter bf = new BinaryFormatter();
            object obj = bf.Deserialize(ms);
            ms.Close();
            ms.Dispose();
            return obj;
        }
        #endregion

        #region 压缩、解压缩
        //压缩字节
        public static byte[] CompressBytes(byte[] bytes)
        {   /*  1.创建压缩的数据流 
                2.设定compressStream为存放被压缩的文件流,并设定为压缩模式
                3.将需要压缩的字节写到被压缩的文件流
            */
            using (MemoryStream compressStream = new MemoryStream())
            {
                using (GZipStream zipStream = new GZipStream(compressStream, CompressionMode.Compress))
                    zipStream.Write(bytes, 0, bytes.Length);
                Array.Resize(ref bytes, 0);
                return compressStream.ToArray();
            }
        }


        //解压缩字节
        public static byte[] Decompress(byte[] bytes)
        {
            /*  1.创建被压缩的数据流
                2.创建zipStream对象，并传入解压的内存流
                3.创建目标流
                4.zipStream拷贝到目标流
                5.返回目标流输出字节
            * */
            byte[] buffer = new byte[4096];//定义数据缓冲  
            using (MemoryStream compressStream = new MemoryStream(bytes))
            {
                using (GZipStream zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
                {
                    using (MemoryStream resultStream = new MemoryStream())
                    {
                        int offset = 0;
                        while ((offset = zipStream.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            resultStream.Write(buffer, 0, offset);
                        }
                        return resultStream.ToArray();
                    }
                }
            }

        }

        //////////////////////////////////////////////////////////////////////////            
        ///读取Stream
        //////////////////////////////////////////////////////////////////////////
        public static int ReadAllBytesFromStream(Stream stream, byte[] buffer)
        {
            int offset = 0;
            int totalCount = 0;
            while (true)
            {
                int bytesRead = stream.Read(buffer, offset, 100);
                if (bytesRead == 0)
                {
                    break;
                }
                offset += bytesRead;
                totalCount += bytesRead;
            }
            return totalCount;
        }

        #endregion
    }

    public class TaskManager
    {
        private Thread taskMonitor = new Thread(new ThreadStart(Kill_InvalidTask));

        public static Hashtable Tasks = new Hashtable();

        public bool CreateTask(TaskType taskType, object param, out string outmsg)
        {
            outmsg = "";
            TaskInfo ti = null;

            do
            {
                ti = new TaskInfo();
            } while (Tasks.Contains(ti.UniqueID));

            if (!ti.CreateTask(taskType, param, out outmsg))
            {
                return false;
            }
            Tasks.Add(ti.UniqueID, ti);
            return true;
        }

        public void SetTouch(String TaskID)
        {
            if (Tasks.Contains(TaskID))
            {
                TaskInfo ti = (TaskInfo)Tasks[TaskID];
                ti.SetTouch();
            }
        }

        public static void Kill_InvalidTask()
        {
            do
            {
                Thread.Sleep(30000);
                try
                {
                    string outmsg = "";
                    DateTime time_now = DateTime.Now;
                    foreach (string key in Tasks.Keys)
                    {
                        try
                        {
                            TaskInfo ti = (TaskInfo)(Tasks[key]);
                            if (ti.PlanEndTime < time_now)
                            {
                                if (ti.EndTask(out outmsg))
                                {
                                    Tasks.Remove(key);
                                }
                            }
                        }
                        catch { }
                        //继续判断其他任务
                    }
                }
                catch { }
            } while (true);
        }
    }

    public class TaskInfo
    {
        TimeSpan _keepTimes = new TimeSpan(0, 15, 0);

        DateTime _startTime;
        public DateTime StartTime
        {
            get { return _startTime; }
        }

        DateTime _touchTime;
        public DateTime LastTouchTime
        {
            get { return _touchTime; }
        }

        DateTime _planEndTime;
        public DateTime PlanEndTime
        {
            get { return _planEndTime; }
        }


        string _id;
        public String UniqueID
        {
            get { return _id; }
        }

        TaskType _taskType;
        object _parameter;

        public TaskInfo(string _ID)
        {
            SetID(_ID);
            _startTime = DateTime.Now;
            _touchTime = _startTime;
            _keepTimes = new TimeSpan(0, 15, 0);
            _planEndTime = _touchTime.Add(_keepTimes);
        }

        public TaskInfo()
        {
            _startTime = DateTime.Now;
            _touchTime = _startTime;
            _keepTimes = new TimeSpan(0, 15, 0);
            SetID(_startTime.Ticks.ToString());
            _planEndTime = _touchTime.Add(_keepTimes);
        }

        public void SetID(string _ID)
        {
            if (string.IsNullOrEmpty(_ID)) return;
            _id = _ID.ToString();
        }

        public void SetTouch()
        {
            _touchTime = DateTime.Now;
            _planEndTime = _touchTime.Add(_keepTimes);
        }

        public void SetKeepTime(TimeSpan ts)
        {
            if (ts.Ticks <= 0) return;

            _keepTimes = ts;
            _planEndTime = _touchTime.Add(_keepTimes);
        }

        public bool CreateTask(TaskType taskType, object param, out string outmsg)
        {
            bool success = false;
            outmsg = "";

            switch (taskType)
            {
                case TaskType.SendFile:
                    if (param.GetType() != typeof(string))
                    {
                        outmsg = "设置[文件发送]任务失败！，参数格式不正确！";
                        return success;
                    }
                    string p = ((string)(param)).Trim();


                    if (string.IsNullOrEmpty(p) || !File.Exists(p))
                    {
                        outmsg = "设置[文件发送]任务失败！，文件不存在！";
                        return success;
                    }

                    _taskType = taskType;
                    _parameter = param;

                    success = true;
                    break;
                default:
                    break;
            }
            return success;
        }

        public bool EndTask(out string outmsg)
        {
            bool success = false;
            outmsg = "";

            switch (_taskType)
            {
                case TaskType.SendFile:
                    string p = ((string)(_parameter)).Trim();

                    if (File.Exists(p))
                    {
                        try
                        {
                            File.Delete(p);
                        }
                        catch (Exception ex)
                        {
                            outmsg = "删除[文件发送]任务失败！\n" + ex.Message;
                        }
                    }
                    success = true;
                    break;
                default:
                    break;
            }
            return success;
        }
    }

    public enum TaskType { SendFile = 1 };
}
